syzlang_parser/
parser.rs

1//! Parse tokens into valid objects
2
3use crate::token::Token;
4use crate::{
5	check_empty, consume, gen_find_by_ident, gen_find_by_name, gen_find_ident, gen_get,
6	gen_get_ident, gen_get_ident_matches, gen_get_iter, gen_get_mut, generror, parsererror, verify,
7	Error, Result,
8};
9
10use log::{debug, error, trace, warn};
11use serde::{Deserialize, Serialize};
12use std::collections::HashMap;
13use std::hash::Hash;
14use std::path::Path;
15use std::str::FromStr;
16
17trait Postproc {
18	fn simplify(&mut self, idents: &HashMap<Identifier, IdentType>) -> Result<usize>;
19	fn fill_in_aliases(&mut self, aliases: &[TypeAlias]) -> Result<usize>;
20	fn fill_in_templates(&mut self, tmpls: &[TypeRaw]) -> Result<usize>;
21}
22
23/// Whether the argument is input, output or both (from perspective of caller)
24#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
25pub enum Direction {
26	In,
27	Out,
28	InOut,
29}
30
31impl Direction {
32	pub fn matches(&self, other: &Self) -> bool {
33		*self == *other || *self == Self::InOut || *other == Self::InOut
34	}
35}
36
37impl FromStr for Direction {
38	type Err = Error;
39
40	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
41		match s {
42			"in" => Ok(Self::In),
43			"out" => Ok(Self::Out),
44			"inout" => Ok(Self::InOut),
45			_ => Err(Error::InvalidString(s.to_string())),
46		}
47	}
48}
49
50/// All the different architectures supported.
51#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
52pub enum Arch {
53	X86,
54	X86_64,
55	Aarch64,
56	Aarch32,
57	Mips64le,
58	Ppc64le,
59	Riscv64,
60	S390x,
61	Mips32,
62	Native,
63}
64impl Arch {
65	pub fn ptr_size(&self) -> usize {
66		match self {
67			Self::X86 | Self::Aarch32 | Self::Mips32 => 4,
68			Self::X86_64 | Self::Aarch64 | Self::Mips64le | Self::Ppc64le | Self::Riscv64 => 8,
69			Self::Native => {
70				#[cfg(target_pointer_width = "32")]
71				{
72					4
73				}
74
75				#[cfg(target_pointer_width = "64")]
76				{
77					8
78				}
79			}
80			_ => todo!(),
81		}
82	}
83	pub fn all() -> Vec<Self> {
84		vec![
85			Arch::X86,
86			Arch::X86_64,
87			Arch::Aarch32,
88			Arch::Aarch64,
89			Arch::Mips64le,
90			Arch::Ppc64le,
91			Arch::Riscv64,
92			Arch::S390x,
93			Arch::Mips32,
94		]
95	}
96}
97
98/// All the operating systems supported
99#[derive(Debug, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
100pub enum Os {
101	Akaros,
102	Darwin,
103	Freebsd,
104	Fuchsia,
105	Linux,
106	Netbsd,
107	Openbsd,
108	Trusty,
109	Windows,
110	All,
111}
112impl Os {
113	pub fn all() -> Vec<Self> {
114		vec![
115			Self::Akaros,
116			Self::Darwin,
117			Self::Freebsd,
118			Self::Fuchsia,
119			Self::Linux,
120			Self::Netbsd,
121			Self::Openbsd,
122			Self::Trusty,
123			Self::Windows,
124		]
125	}
126}
127
128impl FromStr for Os {
129	type Err = Error;
130
131	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
132		match s.to_lowercase().as_str() {
133			"akaros" => Ok(Self::Akaros),
134			"darwin" => Ok(Self::Darwin),
135			"freebsd" => Ok(Self::Freebsd),
136			"fuchsia" => Ok(Self::Fuchsia),
137			"linux" => Ok(Self::Linux),
138			"netbsd" => Ok(Self::Netbsd),
139			"openbsd" => Ok(Self::Openbsd),
140			"trusty" => Ok(Self::Trusty),
141			"windows" => Ok(Self::Windows),
142			"all" => Ok(Self::All),
143			_ => Err(Error::InvalidString(s.to_string())),
144		}
145	}
146}
147
148impl std::fmt::Display for Os {
149	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150		f.write_str(match self {
151			Os::Akaros => "akaros",
152			Os::Darwin => "darwin",
153			Os::Freebsd => "freebsd",
154			Os::Fuchsia => "fuchsia",
155			Os::Linux => "linux",
156			Os::Netbsd => "netbsd",
157			Os::Openbsd => "openbsd",
158			Os::Trusty => "trusty",
159			Os::Windows => "windows",
160			Os::All => "all",
161		})
162	}
163}
164
165impl FromStr for Arch {
166	type Err = Error;
167
168	fn from_str(s: &str) -> Result<Self> {
169		match s {
170			"amd64" | "x86_64" => Ok(Arch::X86_64),
171			"386" | "x86_real" | "x86_16" | "x86_32" => Ok(Arch::X86),
172			"arm64" => Ok(Arch::Aarch64),
173			"arm" => Ok(Arch::Aarch32),
174			"mips64le" => Ok(Arch::Mips64le),
175			"ppc64le" | "ppc64" => Ok(Arch::Ppc64le),
176			"riscv64" => Ok(Arch::Riscv64),
177			"s390x" => Ok(Arch::S390x),
178			"mips32" | "mips" | "mips32be" => Ok(Arch::Mips32),
179			"target" => Ok(Arch::Native),
180			_ => Err(Error::InvalidString(s.to_string())),
181		}
182	}
183}
184
185/// Arbitrary value for some option
186#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
187pub enum Value {
188	/// Integer
189	Int(i64),
190
191	/// String that was enclosed in quotes
192	String(String),
193
194	/// Some identifier, can be known type or unknown reference to flag, etc.
195	Ident(Identifier),
196
197	/// Used when we see '???' in the source files
198	Unknown,
199}
200
201impl Value {
202	fn _parse_as_value(src: &str, base: u32) -> Result<Self> {
203		log::debug!("as value {src} base {base}");
204		if let Ok(v) = i64::from_str_radix(src, base) {
205			Ok(Self::Int(v))
206		} else if let Ok(v) = u64::from_str_radix(src, base) {
207			if v & (1 << 63) != 0 {
208				let rval = if v == i64::MIN as u64 {
209					i64::MIN
210				} else {
211					let twos = -(v as i64) as u64;
212					let twos = twos as i64;
213					-twos
214				};
215				trace!("orig: {v:x} | twos {rval:x} {rval}");
216				Ok(Self::Int(rval))
217			} else {
218				// This shouldn't be possible, I think
219				panic!("unable to parse as i64, but able to parse as u64, but top-most bit not set {src} {base}");
220			}
221		} else if let Some(s) = src.strip_prefix("0x") {
222			assert!(!s.starts_with("0x"));
223			Self::_parse_as_value(s, 16)
224		} else if base == 10 && src.starts_with('"') && src.ends_with('"') {
225			let src = &src[1..src.len() - 1];
226			Ok(Self::String(src.to_string()))
227		} else {
228			// Only give warning here because caller may try Value before
229			// setting as Ident
230			generror!(format!("Unable to parse {src}:{base} as Value"), warn)
231		}
232	}
233	/// Try and parse a string as fixed value
234	///
235	/// ```
236	/// use syzlang_parser::parser::Value;
237	/// assert_eq!(Value::parse_as_value("0x10").unwrap(), Value::Int(16));
238	/// assert_eq!(Value::parse_as_value(r#""abcd""#).unwrap(), Value::String(String::from("abcd")));
239	/// ```
240	pub fn parse_as_value(src: &str) -> Result<Self> {
241		Self::_parse_as_value(src, 10)
242	}
243}
244
245impl TryFrom<&Value> for i64 {
246	type Error = Error;
247
248	fn try_from(value: &Value) -> std::result::Result<Self, Self::Error> {
249		if let Value::Int(n) = value {
250			Ok(*n)
251		} else {
252			Err(Error::Error(format!("cannot parse {value:?} as int")))
253		}
254	}
255}
256
257impl TryFrom<Value> for serde_json::Value {
258	type Error = Error;
259
260	fn try_from(value: Value) -> std::result::Result<Self, Self::Error> {
261		let v = &value;
262		v.try_into()
263	}
264}
265
266impl TryFrom<&Value> for serde_json::Value {
267	type Error = Error;
268
269	fn try_from(value: &Value) -> std::result::Result<Self, Self::Error> {
270		let r = match value {
271			Value::Int(v) => serde_json::to_value(*v)?,
272			Value::String(v) => serde_json::to_value(v)?,
273			Value::Ident(n) => {
274				return generror!(format!("unable to load ident {n:?} as value"));
275			}
276			Value::Unknown => {
277				return Err(Error::Error(String::from(
278					"cannot parse Unknown to serde_json::Value",
279				)))
280			}
281		};
282		Ok(r)
283	}
284}
285
286impl FromStr for Value {
287	type Err = Error;
288
289	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
290		if s == "???" {
291			Ok(Value::Unknown)
292		} else if let Ok(n) = Self::parse_as_value(s) {
293			Ok(n)
294		} else {
295			let ident = Identifier::from_str(s)?;
296			Ok(Value::Ident(ident))
297		}
298	}
299}
300
301impl std::fmt::Display for &Value {
302	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
303		match self {
304			Value::Int(_) => todo!(),
305			Value::String(_) => todo!(),
306			Value::Ident(n) => f.write_str(&n.safe_name()),
307			Value::Unknown => todo!(),
308		}
309	}
310}
311
312impl TryFrom<&Token> for Value {
313	type Error = Error;
314
315	fn try_from(value: &Token) -> std::result::Result<Self, Self::Error> {
316		match value {
317			Token::Char(n) => Ok(Value::Int(*n as i64)),
318			Token::String(n) => Ok(Value::String(n.clone())),
319			Token::Name(n) => Value::from_str(n),
320			_ => generror!(format!("value {value:?} not parsed")),
321		}
322	}
323}
324
325impl TryFrom<Token> for Value {
326	type Error = Error;
327
328	fn try_from(value: Token) -> std::result::Result<Self, Self::Error> {
329		match value {
330			Token::Char(n) => Ok(Value::Int(n as i64)),
331			Token::String(n) => Ok(Value::String(n)),
332			Token::Name(n) => Value::from_str(n.as_str()),
333			_ => generror!(format!("value {value:?} not parsed")),
334		}
335	}
336}
337
338/// A named constant tied to one or more architectures
339#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
340pub struct Const {
341	/// The name
342	pub name: String,
343
344	/// A value, which should be resolved
345	pub value: Value,
346
347	/// The architectures where this value is valid
348	pub arch: Vec<Arch>,
349}
350
351impl Const {
352	pub fn new<S: Into<String>>(name: S, value: Value, arch: Vec<Arch>) -> Self {
353		Self {
354			name: name.into(),
355			value,
356			arch,
357		}
358	}
359	/// Create a new const for all defined architectures.
360	pub fn new_allarch(name: String, value: Value) -> Self {
361		let arch = Arch::all();
362		Self { name, value, arch }
363	}
364	pub fn as_uint(&self) -> Result<u64> {
365		match &self.value {
366			Value::Int(a) => Ok(*a as u64),
367			_ => Err(Error::UnexpectedValue),
368		}
369	}
370
371	/// Get name of the constant
372	pub fn name(&self) -> &str {
373		&self.name
374	}
375
376	/// Get value of the constant
377	pub fn value(&self) -> &Value {
378		&self.value
379	}
380
381	/// Check if constant is valid for a given value
382	pub fn is_for_arch(&self, arch: &Arch) -> bool {
383		self.arch.contains(arch)
384	}
385
386	/// Iterate all the arches, the constant is valid for
387	pub fn arches(&self) -> std::slice::Iter<'_, Arch> {
388		self.arch.iter()
389	}
390
391	/// Parse all tokens into a vector of [Const] values.
392	///
393	/// * `tokens` - All tokens which should be parsed
394	/// * `arches` - An optionally specified architecture, if it isn't contained in the tokens
395	pub fn from_tokens(mut tokens: Vec<Token>, arches: Option<Arch>) -> Result<Vec<Self>> {
396		debug!(
397			"getting const from {} tokens | arches {arches:?}",
398			tokens.len()
399		);
400		Statement::while_comments(&mut tokens)?;
401		if tokens.is_empty() {
402			return Ok(Vec::new());
403		}
404
405		let next = consume!(tokens);
406
407		let mut defarches = if let Ok(n) = next.to_name() {
408			if n == "arches" && matches!(consume!(tokens), Token::Equal) {
409				let mut rem = Statement::until_newline(&mut tokens);
410				let mut ret = Vec::new();
411
412				debug!("tokens bef {rem:?}");
413				rem.retain(|x| *x != Token::Comma);
414				debug!("tokens aft {rem:?}");
415				while !rem.is_empty() {
416					let r = consume!(rem);
417					let r = r.to_name()?;
418					let a = Arch::from_str(r)?;
419					ret.push(a);
420				}
421				ret
422			} else {
423				tokens.insert(0, next);
424				Vec::new()
425			}
426		} else {
427			tokens.insert(0, next);
428			Vec::new()
429		};
430
431		if defarches.is_empty() {
432			defarches = if let Some(n) = arches {
433				vec![n]
434			} else {
435				Vec::new()
436			};
437		}
438		debug!("defarches {defarches:?}");
439		let mut consts = Vec::new();
440
441		while !tokens.is_empty() {
442			let next = consume!(tokens);
443			trace!("next {next:?}");
444			match next {
445				Token::Newline => {}
446				Token::Comment(_) => {}
447				Token::Name(name) => {
448					let mut arches = defarches.clone();
449					let mut rem = Statement::until_newline(&mut tokens);
450					let n = consume!(rem);
451					assert!(matches!(n, Token::Equal));
452					let mut fval = None;
453
454					for parts in rem.split(|x| *x == Token::Comma) {
455						if parts.is_empty() {
456							continue;
457						}
458						let l = parts.len();
459						if let Some(nvalue) = parts.last() {
460							let nvalue: Value = nvalue.try_into()?;
461							let mut narches = Vec::new();
462							for arch in parts[..l - 1].iter() {
463								if matches!(arch, Token::Colon) {
464									continue;
465								}
466								let n = arch.to_name()?;
467								let narch = Arch::from_str(n)?;
468								arches.retain(|x| *x != narch);
469								narches.push(narch);
470							}
471							if nvalue != Value::Unknown {
472								if narches.is_empty() {
473									fval = Some(nvalue);
474								} else {
475									let ins = Self {
476										value: nvalue,
477										name: name.clone(),
478										arch: narches,
479									};
480									consts.push(ins);
481								}
482							}
483						} else {
484							error!("no elements, which indicate multiple successive commas");
485							todo!();
486						}
487					}
488
489					if let Some(value) = std::mem::take(&mut fval) {
490						let ins = Self {
491							value,
492							name: name.clone(),
493							arch: arches,
494						};
495						consts.push(ins);
496					}
497				}
498				_ => {
499					error!("unable to parse {next:?}");
500					todo!()
501				}
502			}
503		}
504		Ok(consts)
505	}
506}
507
508/// Wrapper around a vector of [Const] with some helper functions.
509#[derive(Default, Clone, Debug, serde::Serialize, serde::Deserialize)]
510pub struct Consts {
511	pub consts: Vec<Const>,
512}
513
514impl Consts {
515	pub fn new(consts: Vec<Const>) -> Self {
516		Self { consts }
517	}
518	/// Try and resolve a system call number by name, like `write`
519	pub fn find_sysno(&self, name: &str, arch: &Arch) -> Option<usize> {
520		let name1 = format!("__NR_{name}");
521		let name2 = format!("SYS_{name}");
522		if let Some(n) = self
523			.consts
524			.iter()
525			.position(|x| (x.name == name1 || x.name == name2) && x.arch.contains(arch))
526		{
527			if let Some(v) = self.consts.get(n) {
528				if let Ok(q) = TryInto::<i64>::try_into(&v.value) {
529					Some(q as usize)
530				} else {
531					None
532				}
533			} else {
534				None
535			}
536		} else {
537			None
538		}
539	}
540	pub fn find_sysno_for_any(&self, name: &str) -> Vec<Const> {
541		let name1 = format!("__NR_{name}");
542		let name2 = format!("SYS_{name}");
543		let ret = self
544			.consts
545			.iter()
546			.filter(|x| x.name == name1 || x.name == name2)
547			.cloned()
548			.collect::<Vec<_>>();
549		ret
550	}
551	pub fn all_consts_matching(&self, value: u64, arch: &Arch) -> Vec<Const> {
552		log::debug!("all consts matching {value:x} for {arch:?}");
553		self.consts
554			.iter()
555			.filter(|x| x.arch.contains(arch))
556			.filter(|x| {
557				if let Ok(v) = x.as_uint() {
558					v == value
559				} else {
560					false
561				}
562			})
563			.cloned()
564			.collect::<Vec<_>>()
565	}
566
567	/// Iterate over all the consts
568	pub fn consts(&'_ self) -> std::slice::Iter<'_, Const> {
569		self.consts.iter()
570	}
571
572	/// Push new value without checking if this element is new
573	pub fn push(&mut self, c: Const) {
574		self.consts.push(c)
575	}
576
577	/// Find value based on name and architecture
578	pub fn find_name_arch(&self, name: &str, arch: &Arch) -> Option<&Const> {
579		// self.consts.iter().find(|&c| c.name == name && c.arch.contains(arch) )
580		self.consts
581			.iter()
582			.find(|&c| c.name == name && c.is_for_arch(arch))
583	}
584
585	/// Architecture can be specified on the filename, like:
586	/// `<name>_amd64.const`. This function tries to extract it.
587	pub fn get_arch_from_path(file: &Path) -> Result<Option<Arch>> {
588		let r = if let Some(name) = file.to_str() {
589			let mut parts: Vec<&str> = name.split('.').collect();
590			parts.pop(); // const
591			if let Some(n) = parts.pop() {
592				if n == "txt" {
593					None
594				} else if let Ok(arch) = Arch::from_str(n) {
595					Some(arch)
596				} else if let Some(last) = n.split('_').next_back() {
597					let arch = Arch::from_str(last)?;
598					debug!("using arch {arch:?}");
599					Some(arch)
600				} else {
601					let m = format!("Unable to find arch in {n}");
602					return generror!(m);
603				}
604			} else {
605				let m = format!("Unable to get arch from {parts:?}");
606				return generror!(m);
607			}
608		} else {
609			let m = format!("unable to get str from path {file:?}");
610			return generror!(m);
611		};
612		Ok(r)
613	}
614
615	/// Parse constants from file
616	pub fn create_from_file(&mut self, p: &Path) -> Result<()> {
617		debug!("parsing const file {p:?}");
618		let arch = Consts::get_arch_from_path(p)?;
619		let data = std::fs::read(p)?;
620		let data = std::str::from_utf8(&data)?;
621		let n = Self::create_from_str(data, arch)?;
622		self.add_vec(n);
623		Ok(())
624	}
625
626	/// Create constants from string
627	pub fn create_from_str(s: &str, arch: Option<Arch>) -> Result<Vec<Const>> {
628		let tokens = Token::create_from_str(s)?;
629		let consts = Const::from_tokens(tokens, arch)?;
630		Ok(consts)
631	}
632
633	/// Same as [Self::push], but only add if the element is unique
634	pub fn add_if_new(&mut self, c: Const) -> bool {
635		if let Some(idx) = self
636			.consts
637			.iter()
638			.position(|x| x.name == c.name && x.value == c.value)
639		{
640			if let Some(x) = self.consts.get_mut(idx) {
641				for arch in c.arch {
642					if !x.arch.contains(&arch) {
643						x.arch.push(arch);
644						return true;
645					}
646				}
647				false
648			} else {
649				panic!("Unable to get index we just retrieved");
650			}
651		} else {
652			self.consts.push(c);
653			true
654		}
655	}
656
657	/// Add from a vector, uses [Self::add_if_new] on each element
658	pub fn add_vec(&mut self, mut consts: Vec<Const>) -> usize {
659		let mut ret = 0;
660		while !consts.is_empty() {
661			if self.add_if_new(consts.remove(0)) {
662				ret += 1;
663			}
664		}
665		ret
666	}
667
668	/// Remove all consts not relevant for the specified architecture.
669	///
670	/// Not necessary, but can be used to save memory.
671	pub fn filter_arch(&mut self, arch: &Arch) {
672		self.consts.retain(|x| x.arch.contains(arch));
673	}
674}
675
676/// All the different basic types supported in Syzlang
677#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
678pub enum ArgType {
679	#[serde(rename = "intptr")]
680	Intptr,
681	#[serde(rename = "int8")]
682	Int8,
683	#[serde(rename = "int16")]
684	Int16,
685	#[serde(rename = "int32")]
686	Int32,
687	#[serde(rename = "int64")]
688	Int64,
689	#[serde(rename = "bool")]
690	Bool,
691	#[serde(rename = "csum")]
692	Csum,
693	#[serde(rename = "int16be")]
694	Int16be,
695	#[serde(rename = "int32be")]
696	Int32be,
697	#[serde(rename = "int64be")]
698	Int64be,
699	#[serde(rename = "string")]
700	String,
701	#[serde(rename = "stringnoz")]
702	StringNoz,
703	#[serde(rename = "strconst")]
704	StringConst,
705	#[serde(rename = "len")]
706	Len,
707	#[serde(rename = "proc")]
708	Proc,
709	#[serde(rename = "glob")]
710	Glob,
711	#[serde(rename = "bitsize")]
712	Bitsize,
713	#[serde(rename = "bytesize")]
714	Bytesize,
715	#[serde(rename = "vma")]
716	Vma,
717	#[serde(rename = "vma64")]
718	Vma64,
719	#[serde(rename = "offsetof")]
720	OffsetOf,
721	#[serde(rename = "fmt")]
722	Fmt,
723	#[serde(rename = "ptr")]
724	Ptr,
725	#[serde(rename = "ptr64")]
726	Ptr64,
727	#[serde(rename = "flags")]
728	Flags,
729	#[serde(rename = "const")]
730	Const,
731	#[serde(rename = "text")]
732	Text,
733	#[serde(rename = "void")]
734	Void,
735	#[serde(rename = "array")]
736	Array,
737	#[serde(rename = "compressed_image")]
738	CompressedImage,
739	Ident(Identifier),
740	Template(Identifier),
741}
742
743impl ArgType {
744	pub fn evaluate_size(&self, arch: &Arch) -> Result<usize> {
745		let ret = match self {
746			ArgType::Intptr => Ok(arch.ptr_size()),
747			ArgType::Int8 => Ok(1),
748			ArgType::Int16 => Ok(2),
749			ArgType::Int32 => Ok(4),
750			ArgType::Int64 => Ok(8),
751			ArgType::Bool => Ok(1),
752			ArgType::Csum => Err(Error::Unsupported),
753			ArgType::Int16be => Ok(2),
754			ArgType::Int32be => Ok(4),
755			ArgType::Int64be => Ok(8),
756			ArgType::String => Err(Error::Unsupported),
757			ArgType::StringNoz => Err(Error::Unsupported),
758			ArgType::StringConst => Err(Error::Unsupported),
759			ArgType::Len => Err(Error::Unsupported),
760			ArgType::Proc => Err(Error::Unsupported),
761			ArgType::Glob => Err(Error::Unsupported),
762			ArgType::Bitsize => Err(Error::Unsupported),
763			ArgType::Bytesize => Err(Error::Unsupported),
764			ArgType::Vma => Ok(arch.ptr_size()),
765			ArgType::Vma64 => Ok(8),
766			ArgType::OffsetOf => Err(Error::Unsupported),
767			ArgType::Fmt => Err(Error::Unsupported),
768			ArgType::Ptr => Ok(arch.ptr_size()),
769			ArgType::Ptr64 => Ok(8),
770			ArgType::Flags => Err(Error::Unsupported),
771			ArgType::Const => Err(Error::Unsupported),
772			ArgType::Text => Err(Error::Unsupported),
773			ArgType::Void => Err(Error::Unsupported),
774			ArgType::Array => Err(Error::Unsupported),
775			ArgType::CompressedImage => Err(Error::Unsupported),
776			ArgType::Ident(_) => Err(Error::Unsupported),
777			ArgType::Template(_) => Err(Error::Unsupported),
778		};
779		log::debug!("eval size of {self:?} = {ret:?}");
780		ret
781	}
782
783	pub fn refers_c_string(&self) -> bool {
784		match self {
785			Self::Ident(n) => n.name == "filename",
786			Self::String | Self::StringConst => true,
787			_ => false,
788		}
789	}
790	pub fn is_filename(&self) -> bool {
791		match self {
792			Self::Ident(n) => n.name == "filename",
793			_ => false,
794		}
795	}
796}
797
798impl std::fmt::Display for ArgType {
799	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
800		let v: String = serde_json::to_string(self).unwrap();
801		// Cut enclosing quotes
802		f.write_str(&v[1..v.len() - 1])
803	}
804}
805
806impl TryFrom<Value> for ArgType {
807	type Error = Error;
808
809	fn try_from(value: Value) -> std::result::Result<Self, Self::Error> {
810		match value {
811			Value::Ident(n) => Ok(ArgType::Ident(n)),
812			_ => generror!(format!("unable to convert {value:?} to ArgType")),
813		}
814	}
815}
816
817impl FromStr for ArgType {
818	type Err = Error;
819
820	fn from_str(os: &str) -> std::result::Result<Self, Self::Err> {
821		let s = format!(r#""{os}""#);
822		if let Ok(r) = serde_json::from_str(&s) {
823			Ok(r)
824		} else {
825			// This will happen for every single custom struct/union/resource/type
826			debug!("No ArgType found, treating as ident '{os}'");
827			let mut parts: Vec<String> = os.split('$').map(|x| x.to_string()).collect();
828			let name = parts.remove(0);
829			Ok(ArgType::Ident(Identifier::new(name, parts)))
830		}
831	}
832}
833
834impl ArgType {
835	pub fn is_int(&self) -> bool {
836		matches!(
837			self,
838			ArgType::Intptr | ArgType::Int8 |
839			ArgType::Int16  | ArgType::Int32 |
840			ArgType::Int64 /*| ArgType::Bool*/ | ArgType::Int16be |
841			ArgType::Int32be | ArgType::Int64be
842		)
843	}
844	pub fn is_ptr(&self) -> bool {
845		matches!(self, ArgType::Ptr | ArgType::Ptr64)
846	}
847	pub fn is_vma(&self) -> bool {
848		matches!(self, ArgType::Vma | ArgType::Vma64)
849	}
850	pub fn is_array(&self) -> bool {
851		matches!(self, ArgType::Array)
852	}
853	pub fn bytes_as_int(&self, bytes: &[u8]) -> Result<serde_json::Number> {
854		log::debug!("bytes {bytes:?} into {self:?}");
855		let v = match self {
856			ArgType::Intptr => usize::from_ne_bytes(bytes.try_into().expect("")).into(),
857			ArgType::Int64 => u64::from_ne_bytes(bytes.try_into().expect("")).into(),
858			ArgType::Int32 => u32::from_ne_bytes(bytes.try_into().expect("")).into(),
859			ArgType::Int16 => u16::from_ne_bytes(bytes.try_into().expect("")).into(),
860			ArgType::Int8 => u8::from_ne_bytes(bytes.try_into().expect("")).into(),
861			ArgType::Int64be => u64::from_be_bytes(bytes.try_into().expect("")).into(),
862			ArgType::Int32be => u32::from_be_bytes(bytes.try_into().expect("")).into(),
863			ArgType::Int16be => u16::from_be_bytes(bytes.try_into().expect("")).into(),
864			_ => return Err(Error::Unsupported),
865		};
866		Ok(v)
867	}
868	pub fn matches_name(&self, name: &str) -> bool {
869		if let Self::Ident(n) = self {
870			n.subname.is_empty() && n.name == name
871		} else {
872			false
873		}
874	}
875	pub fn arg_size(&self, ptrsize: usize) -> Result<usize> {
876		match self {
877			ArgType::Intptr => Ok(ptrsize),
878			ArgType::Ptr => Ok(ptrsize),
879			ArgType::Ptr64 => Ok(8),
880			ArgType::Vma => Ok(ptrsize),
881			ArgType::Vma64 => Ok(8),
882			ArgType::Int8 => Ok(1),
883			ArgType::Int16 => Ok(2),
884			ArgType::Int32 => Ok(4),
885			ArgType::Int64 => Ok(8),
886			ArgType::Bool => Ok(1),
887			ArgType::Int16be => Ok(2),
888			ArgType::Int32be => Ok(4),
889			ArgType::Int64be => Ok(8),
890			_ => Err(Error::Unsupported),
891		}
892	}
893	#[cfg(feature = "unstable")]
894	pub fn num_bytes(&self, target: &dyn Target) -> Result<usize> {
895		match self {
896			ArgType::Intptr => Ok(target.target_size()),
897			ArgType::Ptr => Ok(target.target_size()),
898			ArgType::Ptr64 => Ok(8),
899			ArgType::Vma => Ok(target.target_size()),
900			ArgType::Vma64 => Ok(8),
901			ArgType::Int8 => Ok(1),
902			ArgType::Int16 => Ok(2),
903			ArgType::Int32 => Ok(4),
904			ArgType::Int64 => Ok(8),
905			ArgType::Bool => Ok(1),
906			ArgType::Int16be => Ok(2),
907			ArgType::Int32be => Ok(4),
908			ArgType::Int64be => Ok(8),
909			_ => todo!(),
910		}
911	}
912	pub fn big_endian(&self) -> Result<bool> {
913		if self.is_int() || self.is_ptr() || self.is_vma() {
914			Ok(matches!(
915				self,
916				ArgType::Int16be | ArgType::Int32be | ArgType::Int64be
917			))
918		} else {
919			Err(Error::Unsupported)
920		}
921	}
922	#[cfg(feature = "unstable")]
923	pub fn little_endian(&self) -> Result<bool> {
924		Ok(!self.big_endian()?)
925	}
926}
927
928/// Optional arguments to a field in a struct or union.
929#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
930pub enum FieldOpt {
931	Dir(Direction),
932	OutOverlay,
933	Opt,
934}
935
936impl FieldOpt {
937	pub fn from_tokens(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
938		let mut ret = Vec::new();
939		while !tokens.is_empty() {
940			let t = consume!(tokens);
941			match t {
942				Token::Name(n) => {
943					if let Ok(dir) = Direction::from_str(n.as_str()) {
944						ret.push(Self::Dir(dir));
945					} else if n == "out_overlay" {
946						ret.push(Self::OutOverlay);
947					} else {
948						error!("no parsed {n}");
949						todo!();
950					}
951				}
952				_ => todo!(),
953			}
954		}
955		Ok(ret)
956	}
957}
958
959/// Attributes to struct or union
960#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
961pub enum StructAttr {
962	Packed,
963	Varlen,
964	Align(Value),
965	Size(Value),
966}
967
968impl StructAttr {
969	fn from_tokens(tokens: Vec<Token>) -> Result<Vec<Self>> {
970		trace!("tokens {tokens:?}");
971		let mut ret = Vec::new();
972		for part in tokens.split(|x| *x == Token::Comma) {
973			let mut part = part.to_vec();
974			let token = consume!(part);
975			let ins = StructAttr::from_token(token, part)?;
976			ret.push(ins);
977		}
978		Ok(ret)
979	}
980	fn from_token(token: Token, mut tokens: Vec<Token>) -> Result<Self> {
981		match token {
982			Token::Name(n) => match n.as_str() {
983				"varlen" => {
984					assert!(tokens.is_empty());
985					Ok(Self::Varlen)
986				}
987				"packed" => {
988					assert!(tokens.is_empty());
989					Ok(Self::Packed)
990				}
991				"align" | "size" => {
992					consume!(tokens, Token::SquareOpen);
993					let v: Value = consume!(tokens).try_into()?;
994					consume!(tokens, Token::SquareClose);
995					check_empty!(tokens);
996					Ok(if n == "align" {
997						Self::Align(v)
998					} else {
999						Self::Size(v)
1000					})
1001				}
1002				_ => todo!(),
1003			},
1004			_ => {
1005				error!("token {token:?} is unknown as struct attr");
1006				todo!();
1007			}
1008		}
1009	}
1010}
1011
1012/// All the different options we can specify on an argument type
1013#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
1014pub enum ArgOpt {
1015	Dir(Direction),
1016	StructAttr(Vec<StructAttr>),
1017	FieldOpt(Vec<FieldOpt>),
1018	Fmt(usize),
1019	Csum(String),
1020	CsumOf(String),
1021
1022	// Argument is optional
1023	Opt,
1024	Len(Value, Value),
1025	FullArg(Box<Argument>),
1026	Value(Value),
1027	Bits(Value),
1028	Ident(Identifier),
1029	SubIdent(Vec<Identifier>),
1030	Range(Value, Value, Value),
1031
1032	/// Series of tokens not yet parsed. Hapens when we have type templates.
1033	Tokens(Vec<Token>),
1034	Arch(Arch),
1035	ProcOpt(Value, Value),
1036}
1037
1038// macro_rules! find_entry {
1039//     ($name:ident, $entry:ident, $value:ty) => {
1040//         #[allow(unused)]
1041//         pub(crate) fn $name(opts: &[ArgOpt]) -> Option<&$value> {
1042//             for opt in opts.iter() {
1043//                 if let ArgOpt::$entry(n) = opt {
1044//                     return Some(n);
1045//                 }
1046//             }
1047//             None
1048//         }
1049//     };
1050// }
1051
1052impl ArgOpt {
1053	fn direction(opts: &[Self], def: &Direction) -> Direction {
1054		for opt in opts.iter() {
1055			if let ArgOpt::Dir(n) = opt {
1056				return *n;
1057			}
1058		}
1059		*def
1060	}
1061	pub fn same_direction(opts: &[Self], curr: &Direction) -> bool {
1062		for opt in opts.iter() {
1063			if let ArgOpt::Dir(n) = opt {
1064				return n == curr || *n == Direction::InOut;
1065			}
1066		}
1067		*curr == Direction::In
1068	}
1069	pub fn get_subarg(opts: &[Self]) -> Option<&Argument> {
1070		for opt in opts.iter() {
1071			if let ArgOpt::FullArg(n) = opt {
1072				return Some(n);
1073			}
1074		}
1075		None
1076	}
1077
1078	// find_entry! { find_arg, Arg, ArgType }
1079
1080	// pub(crate) fn filter_struct_attr(opts: &[Self]) -> Option<Vec<StructAttr>> {
1081	// 	for opt in opts.iter() {
1082	// 		if let Self::StructAttr(n) = opt {
1083	// 			return Some(n.clone());
1084	// 		}
1085	// 	}
1086	// 	None
1087	// }
1088	// pub(crate) fn filter_field_opt(opts: &[Self]) -> Option<Vec<FieldOpt>> {
1089	// 	for opt in opts.iter() {
1090	// 		if let Self::FieldOpt(n) = opt {
1091	// 			return Some(n.clone());
1092	// 		}
1093	// 	}
1094	// 	None
1095	// }
1096
1097	// pub(crate) fn into_ident(self) -> Result<String> {
1098	// 	match self {
1099	// 		ArgOpt::Ident(n) => Ok(n.unique_name()),
1100	// 		ArgOpt::SubIdent(n) => {
1101	// 			let parts: Vec<String> = n.iter().map(|x| { x.unique_name() }).collect();
1102	// 			let s = parts.join(":");
1103	// 			Ok(s)
1104	// 		},
1105	// 		_ => {
1106	// 			error!("Unable to parse {self:?} as ident");
1107	// 			todo!();
1108	// 		},
1109	// 	}
1110	// }
1111	fn simplify(opts: &mut Vec<Self>, at: &IdentType, argname: &Identifier) -> Result<usize> {
1112		let mut ret = 0;
1113		match at {
1114			IdentType::Resource | IdentType::Struct | IdentType::Union | IdentType::Flag => {
1115				let tokens = Self::remove_tokens(opts);
1116				for tokens in tokens.into_iter() {
1117					for token in tokens.into_iter() {
1118						match &token {
1119							Token::Name(n) => {
1120								if n == "opt" {
1121									opts.push(ArgOpt::Opt);
1122									ret += 1;
1123								} else {
1124									error!("Don't know how to simplify {n}");
1125									todo!();
1126								}
1127							}
1128							_ => {
1129								error!("token {token:?}");
1130								todo!();
1131							}
1132						}
1133					}
1134				}
1135			}
1136			IdentType::Template | IdentType::Alias => {
1137				if argname.name == "fileoff" && opts.is_empty() {
1138					opts.push(ArgOpt::Tokens(vec![Token::Name("int32".to_string())]));
1139					ret += 1;
1140				}
1141			}
1142			IdentType::Function => todo!(),
1143		}
1144		Ok(ret)
1145	}
1146	fn remove_tokens(opts: &mut Vec<Self>) -> Vec<Vec<Token>> {
1147		let rem: Vec<Vec<Token>> = opts
1148			.extract_if(.., |x| matches!(x, ArgOpt::Tokens(_)))
1149			.map(|x| {
1150				if let ArgOpt::Tokens(n) = x {
1151					n
1152				} else {
1153					panic!("");
1154				}
1155			})
1156			.collect();
1157		rem
1158	}
1159
1160	fn from_tokens_const(tokens: Vec<Token>) -> Result<Vec<Self>> {
1161		let mut ret = Vec::new();
1162		for (i, part) in tokens.split(|x| *x == Token::Comma).enumerate() {
1163			let mut part = part.to_vec();
1164
1165			if i == 0 {
1166				let r = consume!(part);
1167				check_empty!(part);
1168				let v: Value = r.try_into()?;
1169				ret.push(Self::Value(v));
1170			} else if i == 1 {
1171				let r = consume!(part);
1172
1173				let a = Self::parse_argtype(r)?;
1174				let extra = Self::parse_arg_opts(&a, &mut part)?;
1175				let inarg = Argument::new_fake(a, extra);
1176				ret.push(Self::FullArg(Box::new(inarg)));
1177				assert!(part.is_empty());
1178			} else {
1179				todo!();
1180			}
1181		}
1182		Ok(ret)
1183	}
1184	fn parse_direction(token: Token) -> Result<Self> {
1185		match token {
1186			Token::Name(n) => match n.as_str() {
1187				"in" => Ok(ArgOpt::Dir(Direction::In)),
1188				"out" => Ok(ArgOpt::Dir(Direction::Out)),
1189				"inout" => Ok(ArgOpt::Dir(Direction::InOut)),
1190				_ => Ok(Self::Ident(Identifier::new(n, vec![]))),
1191			},
1192			_ => generror!(format!("Unable to parse {token:?} as direction")),
1193		}
1194	}
1195	#[cfg(feature = "unstable")]
1196	fn get_argtype_or(opts: &[Self], def: ArgType) -> ArgType {
1197		for opt in opts.iter() {
1198			if let Self::FullArg(a) = opt {
1199				return a.argtype.clone();
1200			}
1201		}
1202		def
1203	}
1204	fn parse_argtype(token: Token) -> Result<ArgType> {
1205		match token {
1206			Token::Name(n) => {
1207				let a = ArgType::from_str(n.as_str())?;
1208				Ok(a)
1209			}
1210			_ => generror!(format!("Unable to parse {token:?} as argtype")),
1211		}
1212	}
1213	fn parse_str(token: Token) -> Result<String> {
1214		match token {
1215			Token::Char(n) => Ok(format!("{n}")),
1216			Token::String(n) => Ok(n),
1217			Token::Name(n) => Ok(n),
1218			_ => generror!(format!("Unable to parse {token:?} as str")),
1219		}
1220	}
1221	fn parse_arg_opts(a: &ArgType, tokens: &mut Vec<Token>) -> Result<Vec<Self>> {
1222		trace!("arg opts {tokens:?}");
1223		let mut ret = Vec::new();
1224		if !tokens.is_empty() && a.is_int() {
1225			consume!(tokens, Token::Colon);
1226			let v: Value = consume!(tokens).try_into()?;
1227			ret.push(Self::Bits(v));
1228		}
1229		Ok(ret)
1230	}
1231	fn from_tokens_str(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1232		let mut ret = Vec::new();
1233		let rem = consume!(tokens);
1234		let v: Value = rem.try_into()?;
1235		ret.push(Self::Value(v));
1236		trace!("rem {tokens:?}");
1237		if let Some(Token::Comma) = tokens.first() {
1238			consume!(tokens, Token::Comma);
1239			let v: Value = consume!(tokens).try_into()?;
1240			ret.push(Self::Value(v));
1241		}
1242		trace!("rem {tokens:?} | got {ret:?}");
1243		assert!(tokens.is_empty());
1244		Ok(ret)
1245	}
1246	fn _name_and_utype(tokens: &mut Vec<Token>) -> Result<Vec<Self>> {
1247		let mut ret = Vec::new();
1248
1249		let name = Statement::parse_nameid(tokens)?;
1250		trace!("found name {name:?}");
1251		let mut namepushed = false;
1252
1253		while !tokens.is_empty() {
1254			trace!("rem {tokens:?}");
1255			let rem = consume!(tokens);
1256			if rem == Token::Colon {
1257				let sn = Statement::parse_nameid(tokens)?;
1258				let mut subnames = vec![name.clone(), sn];
1259
1260				while let Some(Token::Colon) = tokens.first() {
1261					consume!(tokens); // remove :
1262					let sn = Statement::parse_nameid(tokens)?;
1263					subnames.push(sn);
1264				}
1265				ret.push(Self::SubIdent(subnames));
1266				namepushed = true;
1267			} else if rem == Token::Comma {
1268				let a = Statement::parse_nameid(tokens)?;
1269				let a = a.unique_name();
1270				let a = ArgType::from_str(&a)?;
1271				let extra = Self::parse_arg_opts(&a, tokens)?;
1272				let inarg = Argument::new_fake(a, extra);
1273				ret.push(Self::FullArg(Box::new(inarg)));
1274			} else {
1275				panic!("unknown follow {rem:?} {tokens:?} {ret:?}");
1276			}
1277		}
1278		if !namepushed {
1279			ret.insert(0, Self::Ident(name));
1280		}
1281
1282		Ok(ret)
1283	}
1284	fn from_tokens_flags(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1285		let ret = Self::_name_and_utype(&mut tokens)?;
1286		trace!("tokens {tokens:?}");
1287		assert!(tokens.is_empty());
1288		Ok(ret)
1289	}
1290	fn from_tokens_len(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1291		let ret = Self::_name_and_utype(&mut tokens)?;
1292		assert!(tokens.is_empty());
1293		Ok(ret)
1294	}
1295	fn from_tokens_array(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1296		let mut ret = Vec::new();
1297		let atype = Statement::parse_nameid(&mut tokens)?.unique_name();
1298		let atype = ArgType::from_str(&atype)?;
1299
1300		if let Some(Token::SquareOpen) = tokens.first() {
1301			let sidx = Statement::find_stop(&Token::SquareOpen, &tokens).unwrap();
1302			let rem = tokens.drain(0..=sidx).collect();
1303			let subopts = Self::from_tokens(rem, &atype)?;
1304			let inarg = Argument::new_fake(atype, subopts);
1305			let ins = Self::FullArg(Box::new(inarg));
1306			ret.push(ins);
1307		} else {
1308			let inarg = Argument::new_fake(atype, vec![]);
1309			ret.push(Self::FullArg(Box::new(inarg)))
1310		}
1311
1312		if !tokens.is_empty() {
1313			consume!(tokens, Token::Comma);
1314			let from: Value = consume!(tokens).try_into()?;
1315			let to = if !tokens.is_empty() {
1316				consume!(tokens, Token::Colon);
1317				let to: Value = consume!(tokens).try_into()?;
1318				to
1319			} else {
1320				Value::Unknown
1321			};
1322			ret.push(Self::Len(from, to));
1323		}
1324		trace!("rem {tokens:?}");
1325		assert!(tokens.is_empty());
1326		Ok(ret)
1327	}
1328	fn from_tokens_ptr(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1329		let mut ret = Vec::new();
1330		let dir = Self::parse_direction(consume!(tokens))?;
1331		ret.push(dir);
1332		consume!(tokens, Token::Comma);
1333		let atype = Statement::parse_nameid(&mut tokens)?.unique_name();
1334		let atype = ArgType::from_str(&atype)?;
1335		ret.push(Self::FullArg(Box::new(Argument::new_fake(
1336			atype.clone(),
1337			vec![],
1338		))));
1339		while let Some(n) = tokens.first() {
1340			match n {
1341				Token::Comma => {
1342					consume!(tokens, Token::Comma);
1343				}
1344				Token::SquareOpen => {
1345					// We create new argument, so pop what we pushed earlier
1346					assert!(matches!(ret.pop().unwrap(), Self::FullArg(_)));
1347					let sidx = Statement::find_stop(n, &tokens).unwrap();
1348					let rem = tokens.drain(0..=sidx).collect();
1349					let a = atype.clone();
1350					let subopts = Self::from_tokens(rem, &a)?;
1351					let inarg = Argument::new_fake(a, subopts);
1352					let ins = Self::FullArg(Box::new(inarg));
1353					ret.push(ins);
1354				}
1355				Token::Name(n) => match n.as_str() {
1356					"opt" => {
1357						consume!(tokens);
1358						ret.push(Self::Opt)
1359					}
1360					_ => todo!(),
1361				},
1362				_ => {
1363					error!("remaining {tokens:?}");
1364					todo!()
1365				}
1366			}
1367		}
1368		Ok(ret)
1369	}
1370	fn from_tokens_generic(tokens: Vec<Token>) -> Result<Vec<Self>> {
1371		trace!("generic {tokens:?}");
1372		let ret = vec![Self::Tokens(tokens)];
1373		Ok(ret)
1374	}
1375	fn from_tokens_offsetof(tokens: Vec<Token>) -> Result<Vec<Self>> {
1376		let mut ret = Vec::new();
1377		for (i, part) in tokens.split(|x| *x == Token::Comma).enumerate() {
1378			let mut part = part.to_vec();
1379			if i == 0 {
1380				let mut name = Vec::new();
1381				while !part.is_empty() {
1382					let t = consume!(part);
1383					let s = Self::parse_str(t)?;
1384					name.push(Identifier::new(s, vec![]));
1385
1386					if !part.is_empty() {
1387						consume!(part, Token::Colon);
1388					}
1389				}
1390				ret.push(Self::SubIdent(name));
1391			} else if i == 1 {
1392				let t = consume!(part);
1393				check_empty!(part);
1394				let a = Self::parse_argtype(t)?;
1395				let inarg = Argument::new_fake(a, vec![]);
1396				ret.push(Self::FullArg(Box::new(inarg)));
1397			} else {
1398				todo!();
1399			}
1400		}
1401		Ok(ret)
1402	}
1403	fn from_tokens_int(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1404		let mut ret = Vec::new();
1405		while !tokens.is_empty() {
1406			let rem = consume!(tokens);
1407			if rem == Token::Name(String::from("opt")) {
1408				ret.push(Self::Opt);
1409			} else {
1410				let start: Value = rem.try_into()?;
1411				consume!(tokens, Token::Colon);
1412				let stop: Value = consume!(tokens).try_into()?;
1413				let align = if !tokens.is_empty() {
1414					consume!(tokens, Token::Comma);
1415					let align: Value = consume!(tokens).try_into()?;
1416					align
1417				} else {
1418					Value::Unknown
1419				};
1420				let ins = Self::Range(start, stop, align);
1421				ret.push(ins);
1422			}
1423		}
1424		Ok(ret)
1425	}
1426	fn parse_text_arch(t: Token) -> Result<Arch> {
1427		let n = Self::parse_str(t)?;
1428		Arch::from_str(n.as_str())
1429	}
1430	fn from_tokens_vma(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1431		let mut ret = Vec::new();
1432		let val: Value = consume!(tokens).try_into()?;
1433		ret.push(Self::Value(val));
1434		Ok(ret)
1435	}
1436	fn from_tokens_text(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1437		let mut ret = Vec::new();
1438		let arch = Self::parse_text_arch(consume!(tokens))?;
1439		ret.push(Self::Arch(arch));
1440		Ok(ret)
1441	}
1442	fn from_tokens_glob(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1443		let mut ret = Vec::new();
1444		let pattern = Self::parse_str(consume!(tokens))?;
1445		ret.push(Self::Value(Value::String(pattern)));
1446		assert!(tokens.is_empty());
1447		Ok(ret)
1448	}
1449	fn from_tokens_proc(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1450		let mut ret = Vec::new();
1451		let start: Value = consume!(tokens).try_into()?;
1452		consume!(tokens, Token::Comma);
1453		let perproc: Value = consume!(tokens).try_into()?;
1454		ret.push(Self::ProcOpt(start, perproc));
1455
1456		if let Some(Token::Comma) = tokens.first() {
1457			consume!(tokens, Token::Comma);
1458			let atype = Self::parse_argtype(consume!(tokens))?;
1459			let inarg = Argument::new_fake(atype, vec![]);
1460			ret.push(Self::FullArg(Box::new(inarg)));
1461		}
1462		assert!(tokens.is_empty());
1463		Ok(ret)
1464	}
1465	fn from_tokens_fmt(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1466		let mut ret = Vec::new();
1467		let val = Self::parse_str(consume!(tokens))?;
1468		let fmt = match val.as_str() {
1469			"hex" => Self::Fmt(16),
1470			"oct" => Self::Fmt(8),
1471			"dec" => Self::Fmt(10),
1472			_ => todo!(),
1473		};
1474		ret.push(fmt);
1475		if let Some(Token::Comma) = tokens.first() {
1476			consume!(tokens, Token::Comma);
1477			trace!("rem {tokens:?}");
1478			let r = consume!(tokens);
1479			let a = Self::parse_argtype(r)?;
1480			let ins = if let Some(Token::SquareOpen) = tokens.first() {
1481				let lidx = Statement::find_stop(&Token::SquareOpen, &tokens).unwrap();
1482				let rem = tokens.drain(0..=lidx).collect();
1483				let extra = Self::from_tokens(rem, &a)?;
1484				let inarg = Argument::new_fake(a, extra);
1485				Self::FullArg(Box::new(inarg))
1486			} else {
1487				let inarg = Argument::new_fake(a, vec![]);
1488				Self::FullArg(Box::new(inarg))
1489			};
1490			ret.push(ins);
1491		}
1492		assert!(tokens.is_empty());
1493		Ok(ret)
1494	}
1495	fn from_tokens_csum(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
1496		let first = Self::parse_str(consume!(tokens))?;
1497		consume!(tokens, Token::Comma);
1498		let mut sumtype = Self::parse_str(consume!(tokens))?;
1499		consume!(tokens, Token::Comma);
1500		if sumtype == "pseudo" {
1501			let other = Self::parse_str(consume!(tokens))?;
1502			consume!(tokens, Token::Comma);
1503			sumtype.push(':');
1504			sumtype.push_str(other.as_str());
1505		}
1506
1507		let argtype = Self::parse_argtype(consume!(tokens))?;
1508		verify!(tokens.is_empty(), UnexpectedToken);
1509		let inarg = Argument::new_fake(argtype, vec![]);
1510		let ret = vec![
1511			ArgOpt::CsumOf(first),
1512			ArgOpt::Csum(sumtype),
1513			ArgOpt::FullArg(Box::new(inarg)),
1514		];
1515		Ok(ret)
1516	}
1517	pub fn from_tokens(mut tokens: Vec<Token>, utype: &ArgType) -> Result<Vec<Self>> {
1518		trace!("as opts {tokens:?} utype {utype:?}");
1519		if tokens.is_empty() {
1520			return Ok(Vec::new());
1521		}
1522
1523		let lidx = Statement::find_stop(&Token::SquareOpen, &tokens).unwrap();
1524		let mut ntokens: Vec<Token> = tokens.drain(0..=lidx).collect();
1525
1526		consume!(ntokens, Token::SquareOpen);
1527
1528		let r = ntokens.pop().unwrap();
1529		assert_eq!(r, Token::SquareClose);
1530		let mut ret = match utype {
1531			ArgType::Const => Self::from_tokens_const(ntokens),
1532			ArgType::Ptr | ArgType::Ptr64 => Self::from_tokens_ptr(ntokens),
1533			ArgType::String | ArgType::StringNoz => Self::from_tokens_str(ntokens),
1534			ArgType::Flags => Self::from_tokens_flags(ntokens),
1535			ArgType::Array => Self::from_tokens_array(ntokens),
1536			ArgType::Csum => Self::from_tokens_csum(ntokens),
1537			ArgType::Len | ArgType::Bitsize | ArgType::Bytesize => Self::from_tokens_len(ntokens),
1538			ArgType::Ident(_n) => Self::from_tokens_generic(ntokens),
1539
1540			ArgType::Void => {
1541				let r = FieldOpt::from_tokens(ntokens)?;
1542				Ok(vec![ArgOpt::FieldOpt(r)])
1543			}
1544			ArgType::OffsetOf => Self::from_tokens_offsetof(ntokens),
1545			ArgType::Fmt => Self::from_tokens_fmt(ntokens),
1546			ArgType::Vma | ArgType::Vma64 => Self::from_tokens_vma(ntokens),
1547			ArgType::Text => Self::from_tokens_text(ntokens),
1548			ArgType::Proc => Self::from_tokens_proc(ntokens),
1549			ArgType::Glob => Self::from_tokens_glob(ntokens),
1550			ArgType::Int64
1551			| ArgType::Int32
1552			| ArgType::Int16
1553			| ArgType::Int8
1554			| ArgType::Intptr
1555			| ArgType::Int64be
1556			| ArgType::Int32be
1557			| ArgType::Int16be => Self::from_tokens_int(ntokens),
1558			_ => todo!(),
1559		}?;
1560		if let Some(Token::ParenOpen) = tokens.first() {
1561			let lidx = Statement::find_stop(&Token::ParenOpen, &tokens).unwrap();
1562			let mut ntokens: Vec<Token> = tokens.drain(0..=lidx).collect();
1563			consume!(ntokens, Token::ParenOpen);
1564			assert_eq!(ntokens.pop(), Some(Token::ParenClose));
1565			let n = consume!(ntokens);
1566			let dir = Self::parse_direction(n)?;
1567			ret.push(dir);
1568			trace!("rem {ntokens:?}");
1569			assert!(ntokens.is_empty());
1570		}
1571		Ok(ret)
1572	}
1573}
1574
1575macro_rules! try_from_argopt {
1576	($enum:ident, $t:ident) => {
1577		impl TryFrom<ArgOpt> for $t {
1578			type Error = Error;
1579
1580			fn try_from(value: ArgOpt) -> std::result::Result<Self, Self::Error> {
1581				match value {
1582					ArgOpt::$enum(v) => Ok(v),
1583					_ => {
1584						generror!(format!("unable to parse {value:?} to Value"))
1585					}
1586				}
1587			}
1588		}
1589	};
1590}
1591
1592try_from_argopt! { Value, Value }
1593try_from_argopt! { Arch, Arch }
1594try_from_argopt! { Dir, Direction }
1595try_from_argopt! { Ident, Identifier }
1596// try_from_argopt! { Arg, ArgType }
1597
1598/// Information about what a custom named entity refers to
1599#[derive(Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize)]
1600pub enum ArgIdent {
1601	#[default]
1602	Unknown,
1603	Resource(String, ArgType),
1604	Union(String),
1605	Struct(String),
1606	Alias(Identifier),
1607	Template(Statement),
1608}
1609
1610/// Incoming or outgoing named argument
1611#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
1612pub struct Argument {
1613	pub name: Identifier,
1614	pub argtype: ArgType,
1615	pub opts: Vec<ArgOpt>,
1616	aident: Option<ArgIdent>,
1617	sourceidents: Vec<Identifier>,
1618}
1619impl Argument {
1620	/// Construct a "fake" argument, which is essentially just an argument with
1621	/// empty name and no options. Can be used for return values when we need to
1622	/// convert them.
1623	pub fn new_fake(argtype: ArgType, opts: Vec<ArgOpt>) -> Self {
1624		Self {
1625			name: Identifier::default(),
1626			argtype,
1627			opts,
1628			aident: None,
1629			sourceidents: Vec::new(),
1630		}
1631	}
1632	pub fn new<S: Into<String>, T: Into<String>>(name: S, argtype: T, opts: Vec<ArgOpt>) -> Self {
1633		let argtype: String = argtype.into();
1634		let name: String = name.into();
1635		let name = Identifier::new(name, vec![]);
1636		let argtype = ArgType::from_str(&argtype).unwrap();
1637		Self {
1638			name,
1639			argtype,
1640			opts,
1641			aident: None,
1642			sourceidents: Vec::new(),
1643		}
1644	}
1645	pub fn evaluate_size(&self, arch: &Arch) -> Result<usize> {
1646		match self.argtype.evaluate_size(arch) {
1647			Ok(n) => Ok(n),
1648			Err(e) => {
1649				if self.argtype.is_ptr() {
1650					ArgType::Intptr.evaluate_size(arch)
1651				} else {
1652					for opt in self.opts.iter() {
1653						if let ArgOpt::FullArg(a) = opt {
1654							return a.evaluate_size(arch);
1655						}
1656					}
1657					log::warn!(
1658						"unable to evaluate size of {:?} {:?}",
1659						self.name,
1660						self.argtype
1661					);
1662					Err(e)
1663				}
1664			}
1665		}
1666	}
1667	pub fn resolve_to_basic(&self) -> &ArgType {
1668		for opt in self.opts.iter() {
1669			if let ArgOpt::FullArg(a) = opt {
1670				return a.resolve_to_basic();
1671			}
1672		}
1673		&self.argtype
1674	}
1675	pub fn is_ident(&self) -> bool {
1676		matches!(self.argtype, ArgType::Ident(_))
1677	}
1678
1679	#[cfg(feature = "unstable")]
1680	fn read_from_argtype_basic(
1681		atype: &ArgType,
1682		ptr: u64,
1683		force_indirect: bool,
1684		_parsed: &Parsed,
1685		target: &dyn Target,
1686	) -> Result<u64> {
1687		match atype {
1688			ArgType::Intptr
1689			| ArgType::Int8
1690			| ArgType::Int16
1691			| ArgType::Int32
1692			| ArgType::Int64
1693			| ArgType::Bool
1694			| ArgType::Int16be
1695			| ArgType::Int32be
1696			| ArgType::Int64be
1697			| ArgType::Ptr
1698			| ArgType::Ptr64
1699			| ArgType::Vma
1700			| ArgType::Vma64 => {
1701				let sz = atype.num_bytes(target)?;
1702				let convert = atype.big_endian()? != target.big_endian();
1703				let val = if force_indirect {
1704					let mut data = Vec::with_capacity(sz);
1705					target.read_bytes(ptr, &mut data)?;
1706					let mut buf = bytebuffer::ByteBuffer::from(data);
1707					match sz {
1708						1 => buf.read_u8()? as u64,
1709						2 => buf.read_u16()? as u64,
1710						4 => buf.read_u32()? as u64,
1711						8 => buf.read_u64()?,
1712						_ => todo!(),
1713					}
1714				} else {
1715					ptr
1716				};
1717				let val = if convert {
1718					todo!();
1719				} else {
1720					val
1721				};
1722				Ok(val)
1723			}
1724			_ => todo!(),
1725		}
1726	}
1727	#[cfg(feature = "unstable")]
1728	fn find_length(&self, idents: &Vec<Identifier>, actions: &[Action]) -> Result<Option<usize>> {
1729		for (i, action) in actions.iter().enumerate() {
1730			let Action::SetLen(_val, ident, _lt) = action;
1731			debug!("checking if {ident:?} == {:?} | {idents:?}", self.name);
1732
1733			// TODO: Probably want to do a more thorough check
1734			let ismatch = if let Some(oid) = idents.first() {
1735				ident == oid
1736			} else {
1737				*ident == self.name
1738			};
1739			if ismatch {
1740				debug!("found length {i}");
1741				return Ok(Some(i));
1742			}
1743		}
1744		Ok(None)
1745	}
1746	#[cfg(feature = "unstable")]
1747	pub fn read_from(
1748		&self,
1749		ptr: u64,
1750		force_indirect: bool,
1751		dir: &Direction,
1752		parsed: &Parsed,
1753		target: &dyn Target,
1754		actions: &mut Vec<Action>,
1755	) -> Result<(serde_json::Value, usize)> {
1756		let mut idents = Vec::new();
1757		let r = self.read_from_int(
1758			ptr,
1759			force_indirect,
1760			dir,
1761			parsed,
1762			target,
1763			actions,
1764			&mut idents,
1765		)?;
1766		assert!(idents.is_empty());
1767		Ok(r)
1768	}
1769	#[cfg(feature = "unstable")]
1770	#[allow(clippy::too_many_arguments)]
1771	fn read_from_int(
1772		&self,
1773		ptr: u64,
1774		force_indirect: bool,
1775		dir: &Direction,
1776		parsed: &Parsed,
1777		target: &dyn Target,
1778		actions: &mut Vec<Action>,
1779		idents: &mut Vec<Identifier>,
1780	) -> Result<(serde_json::Value, usize)> {
1781		// TODO: This is not calculated correctly It only makes sense to use it
1782		// if we are indirect, but what about when we have multiple
1783		// indirections? What value should be returned?
1784
1785		use serde_json::json;
1786		let mut bytes_read = 0;
1787		debug!("reading {:?} | {:?}", self.argtype, self.name);
1788		let ret = match &self.argtype {
1789			ArgType::Intptr
1790			| ArgType::Int8
1791			| ArgType::Int16
1792			| ArgType::Int32
1793			| ArgType::Int64
1794			| ArgType::Bool
1795			| ArgType::Int16be
1796			| ArgType::Int32be
1797			| ArgType::Int64be
1798			| ArgType::Vma
1799			| ArgType::Vma64 => {
1800				let r = Self::read_from_argtype_basic(
1801					&self.argtype,
1802					ptr,
1803					force_indirect,
1804					parsed,
1805					target,
1806				)?;
1807				let key = self.argtype.to_string();
1808				json!({key: r})
1809			}
1810
1811			ArgType::String | ArgType::StringConst => {
1812				let s = target.read_c_string(ptr)?;
1813				serde_json::to_value(s)?
1814			}
1815			ArgType::StringNoz | ArgType::Array => {
1816				debug!("parsing array");
1817				let itemsz = match &self.argtype {
1818					ArgType::StringNoz => 1,
1819					ArgType::Array => {
1820						if let Some(sub) = ArgOpt::get_subarg(&self.opts) {
1821							if sub.argtype.is_int() {
1822								sub.argtype.num_bytes(target)?
1823							} else {
1824								warn!("array of unknown underlying size, cannot process");
1825								return Err(Error::Unsupported);
1826							}
1827						} else {
1828							error!("Have array, but don't know of what???");
1829							return Err(Error::Unsupported);
1830						}
1831					}
1832					_ => panic!("impossible"),
1833				};
1834				if let Some(idx) = self.find_length(idents, actions)? {
1835					let Action::SetLen(val, _b, lt) = actions.remove(idx);
1836					let len: usize = serde_json::from_value(val)?;
1837					let fsize = match lt {
1838						LenType::Len => len * itemsz,
1839						LenType::Bytes => len,
1840						LenType::Bits => len / 8,
1841						LenType::Offset => len,
1842					};
1843					let mut data = Vec::with_capacity(fsize);
1844					target.read_bytes(ptr, &mut data)?;
1845
1846					// TODO: Should parse it properly
1847					match &self.argtype {
1848						ArgType::Array => json!({"array": data}),
1849						ArgType::StringNoz => json!({"string": data}),
1850						_ => todo!(),
1851					}
1852				} else {
1853					serde_json::Value::Null
1854				}
1855			}
1856			ArgType::OffsetOf | ArgType::Len | ArgType::Bitsize | ArgType::Bytesize => {
1857				let atype = ArgOpt::get_argtype_or(&self.opts, ArgType::Int32);
1858				let v = Self::read_from_argtype_basic(&atype, ptr, force_indirect, parsed, target)?;
1859				let v = serde_json::to_value(v)?;
1860				if let Some(fieldopt) = self.opts.first() {
1861					let ident: Identifier = fieldopt.clone().try_into()?;
1862					let ltype = match &self.argtype {
1863						ArgType::Len => LenType::Len,
1864						ArgType::Bitsize => LenType::Bits,
1865						ArgType::Bytesize => LenType::Bytes,
1866						ArgType::OffsetOf => LenType::Offset,
1867						_ => panic!("Impossible"),
1868					};
1869					actions.push(Action::SetLen(v.clone(), ident, ltype))
1870				} else {
1871					error!("Unable to determine field of for len")
1872				}
1873				let key = self.argtype.to_string();
1874				json!({key: v})
1875			}
1876
1877			ArgType::Ptr | ArgType::Ptr64 => {
1878				if ArgOpt::same_direction(&self.opts, dir) {
1879					let ptr = Self::read_from_argtype_basic(
1880						&self.argtype,
1881						ptr,
1882						force_indirect,
1883						parsed,
1884						target,
1885					)?;
1886					if let Some(narg) = ArgOpt::get_subarg(&self.opts) {
1887						idents.push(self.name.clone());
1888						let (ins, bread) =
1889							narg.read_from_int(ptr, true, dir, parsed, target, actions, idents)?;
1890						idents.pop();
1891						bytes_read += bread;
1892						json!({"ptr": ins})
1893					} else {
1894						return Err(Error::Unsupported);
1895					}
1896				} else {
1897					serde_json::Value::Null
1898				}
1899			}
1900			ArgType::Csum => return Err(Error::Unsupported),
1901			ArgType::Flags => return Err(Error::Unsupported),
1902			ArgType::Const => return Err(Error::Unsupported),
1903			ArgType::Text => return Err(Error::Unsupported),
1904			ArgType::Proc => return Err(Error::Unsupported),
1905			ArgType::Glob => return Err(Error::Unsupported),
1906			ArgType::Fmt => return Err(Error::Unsupported),
1907			ArgType::CompressedImage => return Err(Error::Unsupported),
1908			ArgType::Void => serde_json::Value::Null,
1909			ArgType::Ident(ident) => {
1910				let key = ident.to_string();
1911				if let Some(it) = parsed.identifier_to_ident_type(ident) {
1912					match it {
1913						IdentType::Resource => {
1914							if let Some(stype) = parsed.resource_to_basic_type(ident) {
1915								let r = Self::read_from_argtype_basic(
1916									&stype,
1917									ptr,
1918									force_indirect,
1919									parsed,
1920									target,
1921								)?;
1922								serde_json::to_value(r)?;
1923								json!({key: r})
1924							} else {
1925								return Err(Error::Unsupported);
1926							}
1927						}
1928						IdentType::Struct => {
1929							if let Some(s) = parsed.get_struct(ident) {
1930								let mut ins = HashMap::new();
1931								let mut nptr = ptr;
1932								for arg in s.args() {
1933									let (v, bread) = arg.read_from(
1934										ptr,
1935										force_indirect,
1936										dir,
1937										parsed,
1938										target,
1939										actions,
1940									)?;
1941									nptr += bread as u64;
1942									let name = arg.name.safe_name();
1943									ins.insert(name, v);
1944								}
1945								bytes_read += (nptr - ptr) as usize;
1946								serde_json::to_value(ins)?
1947							} else {
1948								return Err(Error::Unsupported);
1949							}
1950						}
1951						IdentType::Union => return Err(Error::Unsupported),
1952						IdentType::Flag => return Err(Error::Unsupported),
1953						IdentType::Template | IdentType::Alias | IdentType::Function => {
1954							return Err(Error::Unsupported)
1955						}
1956					}
1957				} else {
1958					return Err(Error::Unsupported);
1959				}
1960			}
1961			ArgType::Template(_) => return Err(Error::Unsupported),
1962		};
1963		Ok((ret, bytes_read))
1964	}
1965	fn fill_in_alias(&mut self, alias: &TypeAlias) -> Result<()> {
1966		self.argtype = alias.utype.clone();
1967		self.opts = alias.opts.clone();
1968		self.aident = Some(ArgIdent::Alias(alias.identifier().clone()));
1969		Ok(())
1970	}
1971	fn fill_in_alias_single(&mut self, aliases: &[TypeAlias]) -> Result<usize> {
1972		let mut ret = 0;
1973		if let ArgType::Ident(name) = &self.argtype {
1974			if let Some(alias) = TypeAlias::find_ident(aliases, name) {
1975				self.fill_in_alias(alias)?;
1976				ret += 1;
1977			}
1978		}
1979		for opt in self.opts.iter_mut() {
1980			if let ArgOpt::FullArg(arg) = opt {
1981				ret += arg.fill_in_alias_single(aliases)?;
1982			}
1983		}
1984		if let Some(ArgIdent::Template(stmt)) = &mut self.aident {
1985			match stmt {
1986				Statement::Struct(a) => ret += Self::fill_in_aliases(&mut a.args, aliases)?,
1987				Statement::Union(a) => ret += Self::fill_in_aliases(&mut a.args, aliases)?,
1988				_ => {}
1989			}
1990		}
1991		Ok(ret)
1992	}
1993	fn fill_in_aliases(args: &mut [Argument], aliases: &[TypeAlias]) -> Result<usize> {
1994		let mut ret = 0;
1995		for arg in args.iter_mut() {
1996			ret += arg.fill_in_alias_single(aliases)?;
1997		}
1998		Ok(ret)
1999	}
2000	fn simplify_single(&mut self, idents: &HashMap<Identifier, IdentType>) -> Result<usize> {
2001		let mut ret = 0;
2002		if let ArgType::Ident(n) = &self.argtype {
2003			if let Some(at) = idents.get(n) {
2004				ret += ArgOpt::simplify(&mut self.opts, at, n)?;
2005			} else {
2006				warn!("ident {n:?} was not found in ident map");
2007			}
2008		}
2009		for opt in self.opts.iter_mut() {
2010			if let ArgOpt::FullArg(arg) = opt {
2011				ret += arg.simplify_single(idents)?;
2012			}
2013		}
2014		if let Some(ArgIdent::Template(stmt)) = &mut self.aident {
2015			match stmt {
2016				Statement::Struct(a) => ret += Self::simplify(&mut a.args, idents)?,
2017				Statement::Union(a) => ret += Self::simplify(&mut a.args, idents)?,
2018				_ => {}
2019			}
2020		}
2021		Ok(ret)
2022	}
2023	fn simplify(args: &mut [Argument], idents: &HashMap<Identifier, IdentType>) -> Result<usize> {
2024		let mut ret = 0;
2025		for arg in args.iter_mut() {
2026			ret += arg.simplify_single(idents)?;
2027		}
2028		Ok(ret)
2029	}
2030
2031	fn fill_in_template_single(&mut self, tmpl: &TypeRaw) -> Result<usize> {
2032		let mut tokens = ArgOpt::remove_tokens(&mut self.opts);
2033		if !tokens.is_empty() {
2034			let args = tokens.remove(0);
2035			assert!(tokens.is_empty());
2036			let mut ntokens = Parsed::unpack_template(tmpl, &args)?;
2037			let insname = if let Some(f) = ntokens.first() {
2038				matches!(f, Token::SquareOpen) || matches!(f, Token::BracketOpen)
2039			} else {
2040				false
2041			};
2042			if insname {
2043				ntokens.insert(0, Token::Name(String::from("VIRTUAL")));
2044				let mut stmts = Statement::from_tokens(ntokens)?;
2045				assert!(stmts.len() == 1);
2046				self.argtype = ArgType::Template(tmpl.name.clone());
2047				self.aident = Some(ArgIdent::Template(stmts.remove(0)));
2048				self.sourceidents.push(tmpl.name.clone());
2049				Ok(1)
2050			} else {
2051				ntokens.insert(0, Token::Name(self.name.name.clone()));
2052				let mut arg = Statement::as_argument(ntokens)?;
2053				self.argtype = arg.argtype;
2054				self.opts.append(&mut arg.opts);
2055				self.sourceidents.push(tmpl.name.clone());
2056				Ok(1)
2057			}
2058		} else {
2059			Ok(0)
2060		}
2061	}
2062	fn fill_in_template(&mut self, templates: &[TypeRaw]) -> Result<usize> {
2063		let mut ret = 0;
2064
2065		// First fix up this argument, if we need to
2066		if let ArgType::Ident(name) = &self.argtype {
2067			if let Some(tmpl) = TypeRaw::find_ident(templates, name) {
2068				let plus = self.fill_in_template_single(tmpl)?;
2069				ret += plus;
2070			}
2071		}
2072
2073		// We then look for sub-arguments, this happens if this is a pointer, array, etc.
2074		for (i, opt) in self.opts.iter_mut().enumerate() {
2075			if let ArgOpt::FullArg(arg) = opt {
2076				let plus = arg.fill_in_template(templates)?;
2077				if plus > 0 {
2078					self.opts.remove(i);
2079					return Ok(ret + plus + self.fill_in_template(templates)?);
2080				}
2081			}
2082		}
2083
2084		// If we have created our own template struct, we also try and fix up that
2085		if let Some(ArgIdent::Template(stmt)) = &mut self.aident {
2086			match stmt {
2087				Statement::Struct(a) => ret += Self::fill_in_templates(&mut a.args, templates)?,
2088				Statement::Union(a) => ret += Self::fill_in_templates(&mut a.args, templates)?,
2089				_ => {}
2090			}
2091		}
2092		Ok(ret)
2093	}
2094
2095	pub fn fill_in_templates(args: &mut [Argument], templates: &[TypeRaw]) -> Result<usize> {
2096		let mut ret = 0;
2097		for arg in args.iter_mut() {
2098			if let Ok(add) = arg.fill_in_template(templates) {
2099				ret += add;
2100			} else {
2101				error!("unable to fill in template on arg {arg:?}");
2102			}
2103		}
2104		Ok(ret)
2105	}
2106
2107	// pub(crate) fn into_inner(self) -> (Identifier, ArgType, Vec<ArgOpt>, Option<ArgIdent>) {
2108	//     (self.name, self.argtype, self.opts, self.aident)
2109	// }
2110	gen_get_ident! { name }
2111	gen_get_iter! { opts, ArgOpt }
2112	gen_get! { arg_type, argtype, ArgType }
2113
2114	/// Parse opts to find direction
2115	pub fn direction(&self) -> Direction {
2116		ArgOpt::direction(&self.opts, &Direction::In)
2117	}
2118
2119	/// Find out what the argument refers to, resource, struct, etc.
2120	pub fn arg_refers_to(&self) -> &Option<ArgIdent> {
2121		&self.aident
2122	}
2123
2124	fn split_tokens(tokens: &Vec<Token>, sep: &Token) -> Result<Vec<Vec<Token>>> {
2125		trace!("Splitting {tokens:?}");
2126		let mut ret = Vec::new();
2127		let mut curr = Vec::new();
2128		let mut paren = 0;
2129		let mut bracket = 0;
2130		let mut square = 0;
2131		for t in tokens.iter() {
2132			if paren == 0 && bracket == 0 && square == 0 && *t == *sep {
2133				ret.push(std::mem::take(&mut curr));
2134				continue;
2135			}
2136			match t {
2137				Token::ParenOpen => paren += 1,
2138				Token::ParenClose => paren -= 1,
2139				Token::BracketOpen => bracket += 1,
2140				Token::BracketClose => bracket -= 1,
2141				Token::SquareOpen => square += 1,
2142				Token::SquareClose => square -= 1,
2143				_ => {}
2144			}
2145			curr.push(t.clone());
2146		}
2147		// We should never have trailing separator, so shold always be something here
2148		ret.push(curr);
2149		Ok(ret)
2150	}
2151}
2152
2153/// Information about defined struct
2154#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2155pub struct Struct {
2156	name: Identifier,
2157	args: Vec<Argument>,
2158	opts: Vec<ArgOpt>,
2159}
2160
2161impl Struct {
2162	gen_get_ident! { name }
2163	gen_get_ident_matches! { name }
2164	gen_get_iter! { args, Argument }
2165	gen_get_iter! { opts, ArgOpt }
2166
2167	// pub(crate) fn into_inner(self) -> (Identifier, Vec<Argument>, Vec<ArgOpt>) {
2168	//     (self.name, self.args, self.opts)
2169	// }
2170	pub fn evaluate_size(&self, arch: &Arch) -> Result<usize> {
2171		let mut size = 0;
2172		for arg in self.args.iter() {
2173			let n = arg.evaluate_size(arch)?;
2174			log::debug!("size of {:?} = {n}", arg.name);
2175			size += n;
2176		}
2177		Ok(size)
2178	}
2179}
2180
2181impl Postproc for Struct {
2182	fn fill_in_aliases(&mut self, aliases: &[TypeAlias]) -> Result<usize> {
2183		Argument::fill_in_aliases(&mut self.args, aliases)
2184	}
2185
2186	fn fill_in_templates(&mut self, tmpls: &[TypeRaw]) -> Result<usize> {
2187		Argument::fill_in_templates(&mut self.args, tmpls)
2188	}
2189
2190	fn simplify(&mut self, idents: &HashMap<Identifier, IdentType>) -> Result<usize> {
2191		Argument::simplify(&mut self.args, idents)
2192	}
2193}
2194
2195/// Information about defined union
2196#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2197pub struct Union {
2198	name: Identifier,
2199	args: Vec<Argument>,
2200	opts: Vec<ArgOpt>,
2201}
2202
2203impl Union {
2204	gen_get_ident! { name }
2205	gen_get_ident_matches! { name }
2206	gen_get_iter! { args, Argument }
2207	gen_get_iter! { opts, ArgOpt }
2208
2209	// pub(crate) fn into_inner(self) -> (Identifier, Vec<Argument>, Vec<ArgOpt>) {
2210	//     (self.name, self.args, self.opts)
2211	// }
2212}
2213impl Postproc for Union {
2214	fn fill_in_aliases(&mut self, aliases: &[TypeAlias]) -> Result<usize> {
2215		Argument::fill_in_aliases(&mut self.args, aliases)
2216	}
2217	fn fill_in_templates(&mut self, tmpls: &[TypeRaw]) -> Result<usize> {
2218		Argument::fill_in_templates(&mut self.args, tmpls)
2219	}
2220	fn simplify(&mut self, idents: &HashMap<Identifier, IdentType>) -> Result<usize> {
2221		Argument::simplify(&mut self.args, idents)
2222	}
2223}
2224
2225/// Identifier for any named entity
2226#[derive(Debug, Default, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
2227pub struct Identifier {
2228	pub name: String,
2229
2230	/// Subnames each separated by '$' in Syzlang
2231	pub subname: Vec<String>,
2232}
2233impl std::fmt::Display for &Identifier {
2234	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2235		f.write_str(&self.unique_name())
2236	}
2237}
2238
2239impl From<&str> for Identifier {
2240	fn from(value: &str) -> Self {
2241		Identifier::new(value, vec![])
2242	}
2243}
2244
2245impl FromStr for Identifier {
2246	type Err = Error;
2247
2248	fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
2249		Ok(Self {
2250			name: s.to_string(),
2251			subname: vec![],
2252		})
2253	}
2254}
2255impl From<&Identifier> for String {
2256	fn from(value: &Identifier) -> Self {
2257		value.to_string()
2258	}
2259}
2260// impl TryFrom<ArgOpt> for Identifier {
2261//     type Error = Error;
2262
2263//     fn try_from(value: ArgOpt) -> std::result::Result<Self, Self::Error> {
2264// 		if let ArgOpt::Ident(n) = value {
2265// 			Ok(n)
2266// 		} else {
2267// 			todo!();
2268// 		}
2269//     }
2270// }
2271
2272impl Identifier {
2273	pub fn new<S: Into<String>>(name: S, subname: Vec<String>) -> Self {
2274		Self {
2275			name: name.into(),
2276			subname,
2277		}
2278	}
2279	pub fn unique_name(&self) -> String {
2280		let mut ret = self.name.clone();
2281		for sub in self.subname.iter() {
2282			ret.push('$');
2283			ret.push_str(sub);
2284		}
2285		ret
2286	}
2287	fn as_safe(c: char) -> char {
2288		c
2289	}
2290	pub fn safify(s: &str) -> String {
2291		let mut ret = String::from("");
2292		for c in s.chars() {
2293			ret.push(Self::as_safe(c));
2294		}
2295		ret
2296	}
2297	pub fn safe_name(&self) -> String {
2298		let mut ret = Self::safify(&self.name);
2299		for sub in self.subname.iter() {
2300			ret.push('_');
2301			ret.push_str(Self::safify(sub).as_str());
2302		}
2303		ret
2304	}
2305}
2306
2307/// An Include statement, both file and directory
2308#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2309pub struct Include {
2310	name: String,
2311	is_file: bool,
2312}
2313
2314impl Include {
2315	/// The file or directory which should be included
2316	pub fn name(&self) -> &str {
2317		&self.name
2318	}
2319
2320	/// This is specified with `incdir <...>` in Syzlang
2321	pub fn is_dir(&self) -> bool {
2322		!self.is_file
2323	}
2324
2325	/// This is a regular `include <..>` entry
2326	pub fn is_file(&self) -> bool {
2327		self.is_file
2328	}
2329}
2330
2331/// Complex types are often given aliases. This struct contains what the real
2332/// type is (already procecced).
2333#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2334pub struct TypeAlias {
2335	name: Identifier,
2336	utype: ArgType,
2337	opts: Vec<ArgOpt>,
2338}
2339impl TypeAlias {
2340	gen_get_ident! { name }
2341	gen_get! { underlying_type, utype, ArgType }
2342	gen_get_iter! { opts, ArgOpt }
2343	gen_find_ident! { name }
2344}
2345
2346/// Different types than a type template might create.
2347#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2348pub enum CreateType {
2349	CreateUnion,
2350	CreateStruct,
2351	CreateEntity,
2352}
2353
2354/// [TypeRaw] is more complex than [TypeAlias] because it can declare arbitrary
2355/// new input, as opposed to just type options.
2356///
2357/// In this struct we therefore store a vector of [Token] so that they can be
2358/// processed as usual when we need to declare the new element.
2359#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2360pub struct TypeRaw {
2361	name: Identifier,
2362	tokens: Vec<Token>,
2363	replace: Vec<ArgType>,
2364	ttype: CreateType,
2365}
2366impl TypeRaw {
2367	pub fn new(
2368		name: Identifier,
2369		tokens: Vec<Token>,
2370		replace: Vec<ArgType>,
2371		ttype: CreateType,
2372	) -> Self {
2373		Self {
2374			name,
2375			tokens,
2376			replace,
2377			ttype,
2378		}
2379	}
2380	gen_find_ident! { name }
2381	gen_get_ident! { name }
2382	gen_get_iter! { tokens, Token }
2383	gen_get_iter! { replace, ArgType }
2384	gen_get! { create_type, ttype, CreateType }
2385
2386	/// Find out which index `name` has in the argument list
2387	///
2388	/// So if entry is `type ABC[X,Y] { ... }`, then `argument_index("Y")` would
2389	/// return Some(1).
2390	pub fn argument_index(&self, name: &str) -> Option<usize> {
2391		for (i, r) in self.replace.iter().enumerate() {
2392			if r.matches_name(name) {
2393				return Some(i);
2394			}
2395		}
2396		None
2397	}
2398}
2399
2400/// Information about a resource
2401#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2402pub struct Resource {
2403	pub name: Identifier,
2404	pub atype: ArgType,
2405	pub consts: Vec<Value>,
2406}
2407
2408impl Resource {
2409	// pub(crate) fn into_inner(self) -> (Identifier, ArgType, Vec<Value>) {
2410	//     (self.name, self.atype, self.consts)
2411	// }
2412	gen_get_ident! { name }
2413	gen_get_iter! { specials, consts, Value }
2414	gen_get! { arg_type, atype, ArgType }
2415}
2416
2417/// Information about a function
2418#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2419pub struct Function {
2420	pub name: Identifier,
2421	pub args: Vec<Argument>,
2422	pub output: ArgType,
2423}
2424
2425impl Function {
2426	pub fn new(name: Identifier, args: Vec<Argument>, output: ArgType) -> Self {
2427		Self { name, args, output }
2428	}
2429	/// Wehther this function is virtual to Syzkaller or actually exist on the target OS
2430	pub fn is_virtual(&self) -> bool {
2431		self.name.name.starts_with("syz_")
2432	}
2433	gen_get_ident! { name }
2434	gen_get_ident_matches! { name }
2435	gen_get_iter! { args, Argument }
2436	gen_get! { output, ArgType }
2437	// pub(crate) fn into_inner(self) -> (Identifier, Vec<Argument>, ArgType) {
2438	//     (self.name, self.args, self.output)
2439	// }
2440}
2441impl Postproc for Function {
2442	fn fill_in_aliases(&mut self, aliases: &[TypeAlias]) -> Result<usize> {
2443		Argument::fill_in_aliases(&mut self.args, aliases)
2444	}
2445	fn fill_in_templates(&mut self, tmpls: &[TypeRaw]) -> Result<usize> {
2446		Argument::fill_in_templates(&mut self.args, tmpls)
2447	}
2448	fn simplify(&mut self, idents: &HashMap<Identifier, IdentType>) -> Result<usize> {
2449		Argument::simplify(&mut self.args, idents)
2450	}
2451}
2452
2453/// One flag which specifies one of several possible values
2454#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2455pub struct Flag {
2456	pub name: Identifier,
2457	pub args: Vec<Value>,
2458}
2459
2460impl Flag {
2461	pub fn new<I: Into<Identifier>>(name: I, args: Vec<Value>) -> Self {
2462		let name = name.into();
2463		Self { name, args }
2464	}
2465	gen_get_ident! { name }
2466	gen_get_ident_matches! { name }
2467	gen_get_iter! { args, Value }
2468	// pub(crate) fn into_inner(self) -> (Identifier, Vec<Value>) {
2469	//     (self.name, self.args)
2470	// }
2471}
2472
2473/// A define statement which can be sent to a C preprocessor
2474#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2475pub struct Define {
2476	name: String,
2477	expr: Vec<Token>,
2478}
2479
2480impl Define {
2481	gen_get! { name, str }
2482	gen_get_iter! { tokens, expr, Token }
2483	pub fn first_token(&self) -> Option<&Token> {
2484		self.expr.first()
2485	}
2486}
2487
2488/// All the different type of statements
2489#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2490pub enum Statement {
2491	Include(Include),
2492	TypeAlias(TypeAlias),
2493	TypeRaw(TypeRaw),
2494	Resource(Resource),
2495	Function(Function),
2496	Struct(Struct),
2497	Union(Union),
2498	Flag(Flag),
2499	Define(Define),
2500}
2501
2502macro_rules! impl_try_from {
2503	($s:ident) => {
2504		impl TryFrom<Statement> for $s {
2505			type Error = Error;
2506
2507			fn try_from(value: Statement) -> std::result::Result<Self, Self::Error> {
2508				match value {
2509					Statement::$s(n) => Ok(n),
2510					_ => generror!(format!("expected {} got {value:?}", stringify!($n))),
2511				}
2512			}
2513		}
2514	};
2515}
2516impl_try_from! { Include }
2517impl_try_from! { TypeAlias }
2518impl_try_from! { TypeRaw }
2519impl_try_from! { Resource }
2520impl_try_from! { Function }
2521impl_try_from! { Struct }
2522impl_try_from! { Union }
2523impl_try_from! { Flag }
2524impl_try_from! { Define }
2525
2526impl Statement {
2527	/// Parse in [Statement]s from file.
2528	pub fn from_file(p: &Path) -> Result<Vec<Self>> {
2529		debug!("parsing stmt file {p:?}");
2530		let data = std::fs::read(p)?;
2531		let data = std::str::from_utf8(&data)?;
2532		let n = Self::parse_from_str(data)?;
2533		Ok(n)
2534	}
2535	pub fn identifier(&self) -> Option<&Identifier> {
2536		match self {
2537			Statement::Include(_) => None,
2538			Statement::TypeAlias(a) => Some(&a.name),
2539			Statement::TypeRaw(a) => Some(&a.name),
2540			Statement::Resource(a) => Some(&a.name),
2541			Statement::Function(a) => Some(&a.name),
2542			Statement::Struct(a) => Some(&a.name),
2543			Statement::Union(a) => Some(&a.name),
2544			Statement::Flag(a) => Some(&a.name),
2545			Statement::Define(_) => None,
2546		}
2547	}
2548	pub fn find_by_id<'a>(stmts: &'a [Statement], name: &Identifier) -> Option<&'a Statement> {
2549		for stmt in stmts.iter() {
2550			if let Some(n) = stmt.identifier() {
2551				if n == name {
2552					return Some(stmt);
2553				}
2554			}
2555		}
2556		None
2557	}
2558	/// Convert from [Token]s to [Statement]s
2559	pub fn from_tokens(mut tokens: Vec<Token>) -> Result<Vec<Self>> {
2560		let mut ret = Vec::new();
2561		while !tokens.is_empty() {
2562			let next = consume!(tokens);
2563
2564			match &next {
2565				Token::Include => ret.push(Self::parse_include(true, &mut tokens)?),
2566				Token::Incdir => ret.push(Self::parse_include(false, &mut tokens)?),
2567				Token::Resource => ret.push(Self::parse_resource(&mut tokens)?),
2568				Token::Type => ret.push(Self::parse_type(&mut tokens)?),
2569				Token::Define => ret.push(Self::parse_define(&mut tokens)?),
2570				Token::Meta => Self::parse_meta(&mut tokens)?,
2571				Token::Name(_n) => ret.append(&mut Self::parse_generic_name(next, &mut tokens)?),
2572				Token::Comment(c) => trace!("ignoring comment {c}"),
2573				Token::CrocOpen
2574				| Token::CrocClose
2575				| Token::ParenOpen
2576				| Token::ParenClose
2577				| Token::BracketOpen
2578				| Token::BracketClose
2579				| Token::SquareOpen
2580				| Token::SquareClose
2581				| Token::Colon
2582				| Token::Comma
2583				| Token::Equal
2584				| Token::Dollar => return parsererror!(format!("unexpected token {next:?}")),
2585				Token::Newline => {}
2586				Token::String(_) | Token::Char(_) => {
2587					return parsererror!(format!("unexpected token {next:?}"))
2588				}
2589			}
2590		}
2591		Ok(ret)
2592	}
2593
2594	/// Parse a string as a vector of [Statement]s
2595	pub fn parse_from_str(s: &str) -> Result<Vec<Statement>> {
2596		let tokens = Token::create_from_str(s)?;
2597		let stmts = Self::from_tokens(tokens)?;
2598		Ok(stmts)
2599	}
2600
2601	fn while_comments(tokens: &mut Vec<Token>) -> Result<()> {
2602		while !tokens.is_empty() {
2603			let n = consume!(tokens);
2604			match n {
2605				Token::Comment(_) => {}
2606				Token::Newline => {}
2607				_ => {
2608					tokens.insert(0, n);
2609					break;
2610				}
2611			}
2612		}
2613		Ok(())
2614	}
2615	fn opposite(token: &Token) -> Option<Token> {
2616		match *token {
2617			Token::BracketOpen => Some(Token::BracketClose),
2618			Token::ParenOpen => Some(Token::ParenClose),
2619			Token::CrocOpen => Some(Token::CrocClose),
2620			Token::SquareOpen => Some(Token::SquareClose),
2621			_ => None,
2622		}
2623	}
2624	fn until_newline(tokens: &mut Vec<Token>) -> Vec<Token> {
2625		let sidx = if let Some(s) = tokens.iter().position(|x| *x == Token::Newline) {
2626			s
2627		} else {
2628			tokens.len()
2629		};
2630		let rem = tokens.drain(..sidx).collect();
2631		rem
2632	}
2633	fn find_stop(start: &Token, tokens: &[Token]) -> Option<usize> {
2634		let mut level = 0;
2635		let opposite = Self::opposite(start).unwrap();
2636		for (i, t) in tokens.iter().enumerate() {
2637			if *t == *start {
2638				level += 1;
2639			} else if *t == opposite {
2640				level -= 1;
2641				if level == 0 {
2642					return Some(i);
2643				}
2644			}
2645		}
2646		None
2647	}
2648
2649	fn find_real_token(tokens: &[Token], t: &Token) -> Option<usize> {
2650		let mut croc = 0;
2651		let mut bracket = 0;
2652		let mut paren = 0;
2653		let mut square = 0;
2654		for (i, tok) in tokens.iter().enumerate() {
2655			if *tok == *t {
2656				if croc == 0 && bracket == 0 && paren == 0 && square == 0 {
2657					return Some(i);
2658				}
2659			} else {
2660				match tok {
2661					Token::CrocOpen => croc += 1,
2662					Token::BracketOpen => bracket += 1,
2663					Token::ParenOpen => paren += 1,
2664					Token::SquareOpen => square += 1,
2665					Token::CrocClose => croc -= 1,
2666					Token::BracketClose => bracket -= 1,
2667					Token::ParenClose => paren -= 1,
2668					Token::SquareClose => square -= 1,
2669					_ => {}
2670				}
2671			}
2672		}
2673		if !tokens.is_empty() {
2674			Some(tokens.len())
2675		} else {
2676			None
2677		}
2678	}
2679
2680	fn parse_as_arg_opts(mut tokens: Vec<Token>, arg: &ArgType) -> Result<Vec<ArgOpt>> {
2681		let opts = if let Some(Token::SquareOpen) = tokens.first() {
2682			ArgOpt::from_tokens(tokens, arg)?
2683		} else if !tokens.is_empty() {
2684			let next = consume!(tokens);
2685			if arg.is_int() && next == Token::Colon {
2686				let num: Value = consume!(tokens).try_into()?;
2687
2688				let mut ret = vec![ArgOpt::Bits(num)];
2689				if !tokens.is_empty() {
2690					ret.append(&mut Self::parse_as_arg_opts(tokens, arg)?);
2691				}
2692				ret
2693			} else if next == Token::ParenOpen {
2694				tokens.insert(0, next);
2695				let rem = Statement::extract_section(&mut tokens, true)?;
2696				let r = FieldOpt::from_tokens(rem)?;
2697				let r = ArgOpt::FieldOpt(r);
2698				check_empty!(tokens);
2699				vec![r]
2700			} else {
2701				error!("next {next:?} + {tokens:?}");
2702				todo!();
2703			}
2704		} else {
2705			check_empty!(tokens);
2706			Vec::new()
2707		};
2708		Ok(opts)
2709	}
2710	fn as_argument(mut parts: Vec<Token>) -> Result<Argument> {
2711		trace!("rest {parts:?}");
2712		let name = Statement::parse_nameid(&mut parts)?.unique_name();
2713		let v = Statement::parse_nameid(&mut parts)?;
2714		let utype = v.unique_name();
2715		let nutype = ArgType::from_str(&utype)?;
2716		let opts = Self::parse_as_arg_opts(parts, &nutype)?;
2717
2718		let arg = Argument::new(name, utype, opts);
2719		Ok(arg)
2720	}
2721	fn as_arguments(mut tokens: Vec<Token>, splitter: &Token) -> Result<Vec<Argument>> {
2722		trace!("as args {splitter:?} {tokens:?}");
2723		let mut ret = Vec::new();
2724		if tokens.is_empty() {
2725			return Ok(ret);
2726		}
2727
2728		trace!("starting to parse as args {tokens:?}");
2729		while let Some(nsplit) = Self::find_real_token(&tokens, splitter) {
2730			trace!("comma @ {nsplit}");
2731			let parts: Vec<Token> = tokens.drain(..nsplit).collect();
2732
2733			// There is no trailing comma, so don't do this in the last one
2734			if !tokens.is_empty() {
2735				let t = consume!(tokens); // ,
2736				verify!(t == Token::Comma || t == Token::Newline, UnexpectedToken);
2737			}
2738			trace!("ARG: {parts:?}");
2739			if parts.is_empty() {
2740				continue;
2741			} else if let Some(idx) = parts.iter().position(|x| matches!(*x, Token::Comment(_))) {
2742				// TODO: Should be a bit more clever here
2743				assert!(idx == 0);
2744				debug!("ignoring all because comment: {idx} {parts:?}");
2745				continue;
2746			}
2747			let arg = Self::as_argument(parts)?;
2748			ret.push(arg);
2749		}
2750		Ok(ret)
2751	}
2752
2753	fn parse_as_opts(tokens: &mut Vec<Token>) -> Result<Vec<ArgOpt>> {
2754		while let Some(Token::Newline) = tokens.first() {
2755			consume!(tokens, Token::Newline);
2756		}
2757		trace!("trying to parse opts");
2758		let nopts = if tokens.first() == Some(&Token::SquareOpen) {
2759			let rem = Statement::extract_section(tokens, true)?;
2760
2761			let r = StructAttr::from_tokens(rem)?;
2762			vec![ArgOpt::StructAttr(r)]
2763		} else {
2764			trace!("No opts, got {:?}", tokens.first());
2765			Vec::new()
2766		};
2767		Ok(nopts)
2768	}
2769	fn parse_generic_name(name: Token, tokens: &mut Vec<Token>) -> Result<Vec<Self>> {
2770		trace!("parse name {name:?}");
2771		let mut ret = Vec::new();
2772		tokens.insert(0, name);
2773		let name = Self::parse_nameid(tokens)?;
2774
2775		let first = consume!(tokens);
2776		if first == Token::Equal {
2777			let rem = Self::until_newline(tokens);
2778			let args = Self::parse_values_with_sep(rem, Token::Comma)?;
2779			let flag = Flag { name, args };
2780			ret.push(Statement::Flag(flag));
2781		} else {
2782			tokens.insert(0, first.clone());
2783			let parse = Self::extract_section(tokens, true)?;
2784			trace!("parsing as struct/union/func {parse:?}");
2785			if first == Token::ParenOpen {
2786				trace!("parsing as function");
2787				let args = Self::as_arguments(parse, &Token::Comma)?;
2788				let mut rem = Self::until_newline(tokens);
2789
2790				trace!("rem to newline: {rem:?}");
2791				let output = if let Some(n) = rem.first() {
2792					if *n != Token::ParenOpen {
2793						let tok = consume!(rem);
2794						let n = tok.to_name()?;
2795						ArgType::from_str(n)?
2796					} else {
2797						// If we have no return argument and function attributes, we may hit this
2798						ArgType::Void
2799					}
2800				} else {
2801					ArgType::Void
2802				};
2803				if let Some(Token::ParenOpen) = rem.first() {
2804					let rargs = Self::extract_section(&mut rem, true)?;
2805					warn!("ignoring function attributes {rargs:?}");
2806				}
2807				check_empty!(rem);
2808				let func = Function { name, args, output };
2809				ret.push(Statement::Function(func));
2810			} else if first == Token::BracketOpen || first == Token::SquareOpen {
2811				let is_struct = first == Token::BracketOpen;
2812				trace!("parsing as struct/union {is_struct:?}");
2813
2814				let args = Self::as_arguments(parse, &Token::Newline)?;
2815				trace!("getting struct/union opts");
2816				let opts = Self::parse_as_opts(tokens)?;
2817				trace!("arg entries {args:?}");
2818				let ins = if is_struct {
2819					let ins = Struct { name, args, opts };
2820					trace!("struct {ins:?}");
2821					Statement::Struct(ins)
2822				} else {
2823					let ins = Union { name, args, opts };
2824					trace!("union {ins:?}");
2825					Statement::Union(ins)
2826				};
2827				ret.push(ins);
2828			} else {
2829				todo!();
2830			}
2831		}
2832
2833		Ok(ret)
2834	}
2835	fn parse_include(is_file: bool, tokens: &mut Vec<Token>) -> Result<Self> {
2836		consume!(tokens, Token::CrocOpen);
2837		let name = Self::parse_nameid(tokens)?;
2838		assert!(name.subname.is_empty());
2839		let name = name.name;
2840		trace!("include {name}");
2841		consume!(tokens, Token::CrocClose);
2842		let inc = Include { name, is_file };
2843		Ok(Statement::Include(inc))
2844	}
2845	fn extract_section(tokens: &mut Vec<Token>, remextra: bool) -> Result<Vec<Token>> {
2846		if let Some(first) = tokens.first() {
2847			trace!("first {first:?}");
2848			verify!(
2849				matches!(first, Token::SquareOpen)
2850					|| matches!(first, Token::ParenOpen)
2851					|| matches!(first, Token::BracketOpen)
2852					|| matches!(first, Token::CrocOpen),
2853				UnexpectedToken
2854			);
2855			if let Some(lidx) = Self::find_stop(first, tokens) {
2856				let mut rem: Vec<Token> = tokens.drain(0..=lidx).collect();
2857				if remextra {
2858					consume!(rem);
2859					rem.pop().unwrap();
2860				}
2861				trace!("rem {rem:?}");
2862
2863				Ok(rem)
2864			} else {
2865				parsererror!(format!("unable to close for {first:?}"))
2866			}
2867		} else {
2868			warn!("no data in tokens, ret empty");
2869			Ok(Vec::new())
2870		}
2871	}
2872	fn parse_nameid(tokens: &mut Vec<Token>) -> Result<Identifier> {
2873		let tok = consume!(tokens);
2874		let name = tok.to_name()?;
2875
2876		trace!("nameid parsing {name}");
2877		let mut sname = String::default();
2878		while let Some(Token::Dollar) = tokens.first() {
2879			trace!("got dollar");
2880			consume!(tokens, Token::Dollar);
2881			if !sname.is_empty() {
2882				sname.push('$');
2883			}
2884			sname.push_str(consume!(tokens).to_name()?);
2885		}
2886		let sname = if sname.is_empty() {
2887			vec![]
2888		} else {
2889			vec![sname]
2890		};
2891		Ok(Identifier::new(name, sname))
2892	}
2893	fn parse_values_with_sep(mut tokens: Vec<Token>, sep: Token) -> Result<Vec<Value>> {
2894		let mut ret = Vec::new();
2895		while !tokens.is_empty() {
2896			let ins: Value = consume!(tokens).try_into()?;
2897			ret.push(ins);
2898
2899			if !tokens.is_empty() {
2900				consume!(tokens, sep);
2901			}
2902		}
2903		check_empty!(tokens);
2904		Ok(ret)
2905	}
2906	fn parse_meta(tokens: &mut Vec<Token>) -> Result<()> {
2907		let rem = Self::until_newline(tokens);
2908		warn!("ignoring meta comments {rem:?}");
2909		Ok(())
2910	}
2911	fn parse_define(tokens: &mut Vec<Token>) -> Result<Self> {
2912		let name = consume!(tokens).to_name()?.clone();
2913		trace!("define {name}");
2914		let rem = Self::until_newline(tokens);
2915		warn!("define ignoring {rem:?}");
2916
2917		let ins = Define { name, expr: rem };
2918		Ok(Statement::Define(ins))
2919	}
2920	fn parse_type(tokens: &mut Vec<Token>) -> Result<Self> {
2921		trace!("parsing type");
2922		let mut opts = Vec::new();
2923		let name = Self::parse_nameid(tokens)?;
2924
2925		trace!("type {name:?}");
2926		let replace = if let Some(Token::SquareOpen) = tokens.first() {
2927			let tmpls = Self::extract_section(tokens, true)?;
2928			let mut vals = Self::parse_values_with_sep(tmpls, Token::Comma)?;
2929			let mut repls = Vec::new();
2930			while !vals.is_empty() {
2931				let ins: ArgType = vals.remove(0).try_into()?;
2932				repls.push(ins);
2933			}
2934			repls
2935		} else {
2936			Vec::new()
2937		};
2938		let is_alias = replace.is_empty();
2939		let n = consume!(tokens);
2940
2941		let r = if n == Token::BracketOpen || n == Token::SquareOpen {
2942			trace!("is struct or union alias: {is_alias}");
2943			let ttype = if n == Token::BracketOpen {
2944				CreateType::CreateStruct
2945			} else {
2946				CreateType::CreateUnion
2947			};
2948			tokens.insert(0, n);
2949
2950			let mut instokens = Vec::new();
2951			let mut contents = Self::extract_section(tokens, false)?;
2952			instokens.append(&mut contents);
2953			let first = tokens.first();
2954			if first == Some(&Token::SquareOpen) {
2955				let mut attr = Self::extract_section(tokens, false)?;
2956				instokens.append(&mut attr);
2957			} else {
2958				trace!("next {:?}", tokens.first());
2959			}
2960
2961			let ins = TypeRaw::new(name, instokens, replace, ttype);
2962			Statement::TypeRaw(ins)
2963		} else {
2964			tokens.insert(0, n);
2965			trace!("tokens {tokens:?}");
2966			let mut rem = Self::until_newline(tokens);
2967			trace!("tokens {rem:?}");
2968			trace!("is_alias {is_alias}");
2969
2970			if !is_alias {
2971				let ins = TypeRaw::new(name, rem, replace, CreateType::CreateEntity);
2972				Statement::TypeRaw(ins)
2973			} else {
2974				let utype = Statement::parse_nameid(&mut rem)?;
2975				let stype = ArgType::from_str(&utype.unique_name())?;
2976				assert!(replace.is_empty());
2977				trace!("getting alias opts {stype:?} {rem:?}");
2978
2979				let mut nopts = if let Some(Token::SquareOpen) = rem.first() {
2980					ArgOpt::from_tokens(rem, &stype)?
2981				} else {
2982					if !rem.is_empty() {
2983						warn!("ignoring extra data {rem:?}");
2984						todo!();
2985					}
2986					Vec::new()
2987				};
2988				opts.append(&mut nopts);
2989				let alias = TypeAlias {
2990					name,
2991					utype: stype,
2992					opts,
2993				};
2994				trace!("alias {alias:?}");
2995				Statement::TypeAlias(alias)
2996			}
2997		};
2998		Ok(r)
2999	}
3000	fn parse_resource(tokens: &mut Vec<Token>) -> Result<Self> {
3001		let mut rem = Self::until_newline(tokens);
3002		trace!("resource {rem:?}");
3003		let tok = consume!(rem);
3004		let name = tok.to_name()?;
3005		let mut opts = Self::extract_section(&mut rem, true)?;
3006		let opt = consume!(opts);
3007		let utype = opt.to_name()?;
3008		let atype = ArgType::from_str(utype)?;
3009		let consts = if let Some(Token::Colon) = rem.first() {
3010			consume!(rem, Token::Colon);
3011			// let rem = Self::until_newline(rem);
3012			Self::parse_values_with_sep(rem, Token::Comma)?
3013		} else {
3014			Vec::new()
3015		};
3016		let name = Identifier::new(name, vec![]);
3017
3018		let ins = Resource {
3019			name,
3020			atype,
3021			consts,
3022		};
3023		Ok(Statement::Resource(ins))
3024	}
3025}
3026
3027// macro_rules! gen_get_filter {
3028//     ($name:ident, $stmts:ident, $entry:ident, $rval:ty) => {
3029//         pub fn $name(&self) -> Vec<&$rval> {
3030//             self.$stmts
3031//                 .iter()
3032//                 .filter_map(|x| {
3033//                     if let Statement::$entry(f) = x {
3034//                         Some(f)
3035//                     } else {
3036//                         None
3037//                     }
3038//                 })
3039//                 .collect()
3040//         }
3041//     };
3042// }
3043
3044/// All the different statements we define for [Identifier]
3045#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
3046pub enum IdentType {
3047	Resource,
3048	Struct,
3049	Union,
3050	Flag,
3051	Template,
3052	Alias,
3053	Function,
3054}
3055
3056#[cfg(feature = "unstable")]
3057#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
3058pub enum LenType {
3059	Len,
3060	Bytes,
3061	Bits,
3062	Offset,
3063}
3064
3065#[cfg(feature = "unstable")]
3066#[derive(Clone, Debug)]
3067pub enum Action {
3068	SetLen(serde_json::Value, Identifier, LenType),
3069}
3070
3071#[cfg(feature = "unstable")]
3072pub trait Target {
3073	fn read_bytes(&self, ptr: u64, data: &mut Vec<u8>) -> Result<usize>;
3074	fn read_c_string(&self, ptr: u64) -> Result<String>;
3075	fn target_size(&self) -> usize;
3076	fn big_endian(&self) -> bool;
3077}
3078
3079/// Final output object after parsing all files.
3080#[derive(Clone, Default, Debug, Serialize, Deserialize)]
3081pub struct Parsed {
3082	pub consts: Consts,
3083	includes: Vec<Include>,
3084	aliases: Vec<TypeAlias>,
3085	templates: Vec<TypeRaw>,
3086	pub resources: Vec<Resource>,
3087	pub functions: Vec<Function>,
3088	pub structs: Vec<Struct>,
3089	unions: Vec<Union>,
3090	pub flags: Vec<Flag>,
3091	defines: Vec<Define>,
3092
3093	#[serde(skip)]
3094	idtypes: HashMap<Identifier, IdentType>,
3095
3096	#[serde(skip)]
3097	idbanned: Vec<Identifier>,
3098}
3099
3100impl Parsed {
3101	/// Construct a new [Parsed] object
3102	pub fn new(consts: Consts, stmts: Vec<Statement>) -> Result<Self> {
3103		let includes = Vec::new();
3104		let aliases = Vec::new();
3105		let templates = Vec::new();
3106		let resources = Vec::new();
3107		let functions = Vec::new();
3108		let structs = Vec::new();
3109		let unions = Vec::new();
3110		let flags = Vec::new();
3111		let defines = Vec::new();
3112		let idtypes = HashMap::new();
3113		let idbanned = Vec::new();
3114		let mut ret = Self {
3115			consts,
3116			includes,
3117			aliases,
3118			templates,
3119			resources,
3120			functions,
3121			structs,
3122			unions,
3123			flags,
3124			defines,
3125			idtypes,
3126			idbanned,
3127		};
3128		ret.insert_stmts(stmts);
3129		// ret.insert_builtin()?;
3130		Ok(ret)
3131	}
3132	gen_get_iter! { includes, Include }
3133	gen_get_iter! { aliases, TypeAlias }
3134	gen_get_iter! { templates, TypeRaw }
3135	gen_get_iter! { resources, Resource }
3136	gen_get_iter! { functions, Function }
3137	gen_get_iter! { structs, Struct }
3138	gen_get_iter! { unions, Union }
3139	gen_get_iter! { flags, Flag }
3140	gen_get_iter! { defines, Define }
3141	gen_get! { consts, Consts }
3142	gen_get_mut! { consts_mut, consts, Consts }
3143
3144	/// Figure out which [IdentType] a certain identifier has.
3145	pub fn identifier_to_ident_type(&self, ident: &Identifier) -> Option<&IdentType> {
3146		self.idtypes.get(ident)
3147	}
3148	/// Figure out which [IdentType] a certain identifier has.
3149	pub fn name_to_ident_type(&self, name: &str) -> Option<&IdentType> {
3150		let ident = Identifier::new(name, vec![]);
3151		self.idtypes.get(&ident)
3152	}
3153	gen_find_by_ident! { get_flag, flags, Flag }
3154	gen_find_by_ident! { get_struct, structs, Struct }
3155	gen_find_by_ident! { get_union, unions, Union }
3156	gen_find_by_ident! { get_resource, resources, Resource }
3157	gen_find_by_ident! { get_function, functions, Function }
3158
3159	gen_find_by_name! { get_named_struct, structs, Struct }
3160	gen_find_by_name! { get_named_union, unions, Union }
3161	gen_find_by_name! { get_named_resource, resources, Resource }
3162	gen_find_by_name! { get_named_function, functions, Function }
3163
3164	fn _resource_to_basics(&self, ident: &Identifier, data: &mut Vec<ArgType>) {
3165		debug!("resolving {ident:?}");
3166		for res in self.resources.iter() {
3167			if res.name == *ident {
3168				let res = res.arg_type();
3169				debug!("found {res:?}");
3170				data.push(res.clone());
3171				if let ArgType::Ident(n) = res {
3172					self._resource_to_basics(n, data)
3173				}
3174			}
3175		}
3176	}
3177	pub fn resource_to_basics(&self, ident: &Identifier) -> Vec<ArgType> {
3178		let mut ret = Vec::new();
3179		self._resource_to_basics(ident, &mut ret);
3180		ret
3181	}
3182
3183	/// Find out the underlying basic type of some resource.
3184	pub fn resource_to_basic_type(&self, ident: &Identifier) -> Option<ArgType> {
3185		debug!("resolving {ident:?}");
3186		for res in self.resources.iter() {
3187			if res.name == *ident {
3188				let res = res.arg_type();
3189				debug!("found {res:?}");
3190				match res {
3191					ArgType::Ident(n) => return self.resource_to_basic_type(n),
3192					_ => return Some(res.clone()),
3193				}
3194			}
3195		}
3196		None
3197	}
3198
3199	/// Remove all functions defined as virtual
3200	pub fn remove_virtual_functions(&mut self) {
3201		let q = self
3202			.functions
3203			.extract_if(.., |x| x.is_virtual())
3204			.collect::<Vec<_>>();
3205		debug!("rem(virt): {}", q.len());
3206	}
3207	pub fn remove_func_no_sysno(&mut self, arch: &Arch) {
3208		let q = self
3209			.functions
3210			.extract_if(.., |x| self.consts.find_sysno(&x.name.name, arch).is_none())
3211			.collect::<Vec<_>>();
3212		debug!("rem(sysno): {}", q.len());
3213	}
3214	pub fn remove_subfunctions(&mut self) {
3215		let q = self
3216			.functions
3217			.extract_if(.., |x| !x.name.subname.is_empty())
3218			.collect::<Vec<_>>();
3219		debug!("rem(sub): {}", q.len());
3220	}
3221	pub fn remove_aliases(&mut self) {
3222		self.aliases.clear();
3223	}
3224	pub fn remove_templates(&mut self) {
3225		self.templates.clear();
3226	}
3227	pub fn remove_defines(&mut self) {
3228		self.defines.clear();
3229	}
3230	pub fn remove_unions(&mut self) {
3231		self.unions.clear();
3232	}
3233	pub fn remove_structs(&mut self) {
3234		self.structs.clear();
3235	}
3236
3237	/// Insert builtin aliases and templates.
3238	///
3239	/// This is necessary, if one uses data from Syzkaller and want to call [Self::postprocess].
3240	pub fn insert_builtin(&mut self) -> Result<()> {
3241		let builtins = r#"
3242type bool8	int8[0:1]
3243type bool16	int16[0:1]
3244type bool32	int32[0:1]
3245type bool64	int64[0:1]
3246type boolptr	intptr[0:1]
3247
3248type fileoff[BASE] BASE
3249
3250type filename string[filename]
3251
3252type buffer[DIR] ptr[DIR, array[int8]]
3253
3254# These are not documented, men seems to be standard
3255type optional[ARG] ARG
3256# TODO: openbsd also uses this with a single argument, B is presumably
3257# then some default value
3258type bytesize4[A,B] bytesize[A, B]
3259type bytesize8[A,B] bytesize[A, B]
3260"#;
3261
3262		let tokens = Token::create_from_str(builtins)?;
3263		let stmts = Statement::from_tokens(tokens)?;
3264		self.insert_stmts(stmts);
3265
3266		Ok(())
3267	}
3268	fn insert_idtype(&mut self, ident: &Identifier, it: IdentType) {
3269		if !self.idbanned.contains(ident) {
3270			if let Some(old) = self.idtypes.insert(ident.clone(), it.clone()) {
3271				if old != it {
3272					// TODO: Might need to use a vector in hashmap
3273					warn!("equal ident for multiple different types {ident:?} {old:?} -> {it:?}");
3274					self.idtypes.remove(ident);
3275					self.idbanned.push(ident.clone());
3276				}
3277			}
3278		} else {
3279			warn!("not inserting {ident:?} because it has caused problems");
3280		}
3281	}
3282	fn insert_stmts(&mut self, stmts: Vec<Statement>) {
3283		for stmt in stmts.into_iter() {
3284			match stmt {
3285				Statement::Include(a) => self.includes.push(a),
3286				Statement::TypeAlias(a) => {
3287					self.insert_idtype(&a.name, IdentType::Alias);
3288					self.aliases.push(a);
3289				}
3290				Statement::TypeRaw(a) => {
3291					self.insert_idtype(&a.name, IdentType::Template);
3292					self.templates.push(a)
3293				}
3294				Statement::Resource(a) => {
3295					self.insert_idtype(&a.name, IdentType::Resource);
3296					self.resources.push(a)
3297				}
3298				Statement::Function(a) => {
3299					self.insert_idtype(&a.name, IdentType::Function);
3300					self.functions.push(a)
3301				}
3302				Statement::Struct(a) => {
3303					self.insert_idtype(&a.name, IdentType::Struct);
3304					self.structs.push(a)
3305				}
3306				Statement::Union(a) => {
3307					self.insert_idtype(&a.name, IdentType::Union);
3308					self.unions.push(a)
3309				}
3310				Statement::Flag(a) => {
3311					self.insert_idtype(&a.name, IdentType::Flag);
3312					self.flags.push(a)
3313				}
3314				Statement::Define(a) => self.defines.push(a),
3315			}
3316		}
3317	}
3318
3319	fn process_aliases_gen<P: Postproc>(args: &mut [P], aliases: &[TypeAlias]) -> Result<usize> {
3320		let mut ret = 0;
3321		for arg in args.iter_mut() {
3322			ret += arg.fill_in_aliases(aliases)?;
3323		}
3324		Ok(ret)
3325	}
3326	fn process_templates_gen<P: Postproc>(args: &mut [P], tmpls: &[TypeRaw]) -> Result<usize> {
3327		let mut ret = 0;
3328		for arg in args.iter_mut() {
3329			ret += arg.fill_in_templates(tmpls)?;
3330		}
3331		Ok(ret)
3332	}
3333	fn simplify_gen<P: Postproc>(
3334		args: &mut [P],
3335		idents: &HashMap<Identifier, IdentType>,
3336	) -> Result<usize> {
3337		let mut ret = 0;
3338		for arg in args.iter_mut() {
3339			ret += arg.simplify(idents)?;
3340		}
3341		Ok(ret)
3342	}
3343	/// Simplify / correct statements since there can be some ambiguity when
3344	/// parsing.
3345	///
3346	/// If for instance, we see `some_id[...]`, we don't really know what
3347	/// `some_id` refers to and therefore don't know how to parse the contents
3348	/// in brackets.
3349	pub fn simplify_and_fix(&mut self) -> Result<usize> {
3350		let mut ret = 0;
3351		let idents = std::mem::take(&mut self.idtypes);
3352		ret += Self::simplify_gen(&mut self.structs, &idents)?;
3353		ret += Self::simplify_gen(&mut self.unions, &idents)?;
3354		ret += Self::simplify_gen(&mut self.functions, &idents)?;
3355		self.idtypes = idents;
3356		Ok(ret)
3357	}
3358
3359	/// Parse and replace all aliases.
3360	pub fn process_aliases(&mut self) -> Result<usize> {
3361		let mut ret = 0;
3362		ret += Self::process_aliases_gen(&mut self.structs, &self.aliases)?;
3363		ret += Self::process_aliases_gen(&mut self.unions, &self.aliases)?;
3364		ret += Self::process_aliases_gen(&mut self.functions, &self.aliases)?;
3365		Ok(ret)
3366	}
3367	/// Unpack templates and create the necessary entities specific for the
3368	/// configured template.
3369	///
3370	/// This step may create new entities, so previous postproceccing may need
3371	/// to be redone based on this. Since this unpacks templates, the size of
3372	/// the data will increase. On Linux, it goes from about 8MB of JSON to 14MB
3373	/// of JSON.
3374	pub fn process_templates(&mut self) -> Result<usize> {
3375		let mut ret = 0;
3376		ret += Self::process_templates_gen(&mut self.structs, &self.templates)?;
3377		ret += Self::process_templates_gen(&mut self.unions, &self.templates)?;
3378		ret += Self::process_templates_gen(&mut self.functions, &self.templates)?;
3379		Ok(ret)
3380	}
3381
3382	/// Perform post-processing on all the defined statements.
3383	///
3384	/// This function does 3 different things in a loop until there is nothing
3385	/// more to do:
3386	///
3387	/// 1. [Self::simplify_and_fix]
3388	/// 2. [Self::process_aliases]
3389	/// 3. [Self::process_templates]
3390	///
3391	/// The function returns the number of items replaced
3392	pub fn postprocess(&mut self) -> Result<usize> {
3393		let mut ret = 0;
3394		let mut i = 0;
3395		loop {
3396			let mut r = 0;
3397			r += self.simplify_and_fix()?;
3398			debug!("PARSED[{i}]: SIMPLIFIED: {r}");
3399			r += self.process_aliases()?;
3400			debug!("PARSED[{i}]: ALIASES: {r}");
3401			r += self.process_templates()?;
3402			debug!("PARSED[{i}]: TEMPLATE {r}");
3403			if r == 0 {
3404				break;
3405			}
3406			ret += r;
3407			i += 1;
3408		}
3409		Ok(ret)
3410	}
3411
3412	/// Is post-processing has been done, we can remove various aliases and
3413	/// temporary structures we don't need.
3414	pub fn clear_unneeded(&mut self) -> Result<()> {
3415		self.aliases.clear();
3416		self.templates.clear();
3417		self.idtypes.clear();
3418		Ok(())
3419	}
3420
3421	/// Unpack a template with the given arguments and return a new token
3422	/// vector.
3423	///
3424	/// The returning vector can be passed to [Statement::from_tokens] to get
3425	/// one or more new statements.
3426	pub fn unpack_template(tmpl: &TypeRaw, args: &Vec<Token>) -> Result<Vec<Token>> {
3427		trace!("template token {tmpl:?} | {args:?}");
3428		let args = Argument::split_tokens(args, &Token::Comma)?;
3429		trace!("args: {args:?}");
3430		verify!(args.len() == tmpl.replace.len(), UnexpectedLength);
3431		let mut ret = Vec::with_capacity(tmpl.tokens.len());
3432		for token in tmpl.tokens.iter() {
3433			match token {
3434				Token::Name(n) => {
3435					if let Some(idx) = tmpl.argument_index(n) {
3436						verify!(idx < args.len(), UnexpectedLength);
3437						ret.append(&mut args[idx].clone());
3438					} else {
3439						ret.push(token.clone())
3440					}
3441				}
3442				_ => ret.push(token.clone()),
3443			}
3444		}
3445		Ok(ret)
3446	}
3447
3448	pub fn assemble(stmts: &str, consts: &str, arch: Option<Arch>) -> Result<Parsed> {
3449		let consts = Self::get_consts(consts, arch)?;
3450		trace!("consts {consts:?}");
3451		let stmts = Self::get_stmts(stmts)?;
3452		trace!("stmts {stmts:?} {consts:?}");
3453		let consts = Consts::new(consts);
3454		let mut parsed = Parsed::new(consts, stmts)?;
3455		parsed.insert_builtin()?;
3456		parsed.postprocess()?;
3457		Ok(parsed)
3458	}
3459	fn get_consts(s: &str, arch: Option<Arch>) -> Result<Vec<Const>> {
3460		let tokens = Token::create_from_str(s)?;
3461		trace!("tokens {tokens:?}");
3462		let consts = Const::from_tokens(tokens, arch)?;
3463		trace!("consts {consts:?}");
3464		Ok(consts)
3465	}
3466	fn get_stmts(s: &str) -> Result<Vec<Statement>> {
3467		let tokens = Token::create_from_str(s)?;
3468		let stmts = Statement::from_tokens(tokens)?;
3469		Ok(stmts)
3470	}
3471}
3472
3473#[cfg(test)]
3474mod tests {
3475	use super::*;
3476	use std::path::PathBuf;
3477
3478	#[test]
3479	fn parse_types() {
3480		assert_eq!(Direction::from_str("in").unwrap(), Direction::In);
3481		let os = Os::from_str("lINux").unwrap();
3482		assert_eq!(os.to_string(), "linux");
3483		assert_eq!(Arch::from_str("amd64").unwrap(), Arch::X86_64);
3484
3485		assert_eq!(ArgType::Intptr.to_string(), "intptr");
3486
3487		assert_eq!(Arch::all().len(), 9);
3488		assert_eq!(Os::all().len(), 9);
3489		assert_eq!(Os::Akaros.to_string(), "akaros");
3490		assert_eq!(Os::Trusty, Os::from_str("trusty").unwrap());
3491		assert_eq!(Os::Netbsd, Os::from_str("NetBsd").unwrap());
3492
3493		assert_eq!(
3494			serde_json::Value::try_from(Value::Int(2))
3495				.unwrap()
3496				.to_string(),
3497			"2"
3498		);
3499
3500		let opts = vec![ArgOpt::Dir(Direction::In)];
3501
3502		assert_eq!(ArgOpt::direction(&opts, &Direction::Out), Direction::In);
3503		assert!(!ArgOpt::same_direction(&opts, &Direction::Out));
3504	}
3505
3506	#[test]
3507	fn single_include0() {
3508		let s1 = r#"arches = amd64"#;
3509		let s2 = r#"
3510include <linux/socket.h>
3511include <linux/ptrace.h>
3512include <linux/resource.h>		
3513		"#;
3514		let _p = Parsed::assemble(s2, s1, None).unwrap();
3515	}
3516
3517	#[test]
3518	fn single_ints0() {
3519		let s1 = r#"
3520arches = amd64
3521__NR_fake = 1
3522"#;
3523		let s2 = r#"
3524resource fd[int32]: 1
3525resource fd[int32]: 0x1000
3526type abc1 const[0xffff]
3527type abc2 const[0xffffffff]
3528type abc3 const[0x0fffffffffffffff]
3529syz_some(a const[0x1])
3530syz_some(b const[-1])
3531fake(fd fd)
3532		"#;
3533		let p = Parsed::assemble(s2, s1, None).unwrap();
3534		let _r = p.consts.find_name_arch("__NR_fake", &Arch::X86_64).unwrap();
3535		assert!(p.consts.find_name_arch("__NR_fake", &Arch::X86).is_none());
3536		assert_eq!(p.consts.find_sysno("fake", &Arch::X86_64).unwrap(), 1);
3537		assert!(p.consts.find_sysno("fake", &Arch::X86).is_none());
3538	}
3539
3540	#[test]
3541	fn path0() {
3542		let p = PathBuf::from("abcd_amd64.const");
3543		assert_eq!(
3544			Consts::get_arch_from_path(p.as_path()).unwrap().unwrap(),
3545			Arch::X86_64
3546		);
3547		let p = PathBuf::from("abcd_qwer.const");
3548		assert!(Consts::get_arch_from_path(p.as_path()).is_err());
3549	}
3550
3551	#[test]
3552	fn single_calls0() {
3553		let s1 = r#"
3554arches = amd64
3555__NR_fake = 1
3556"#;
3557		let s2 = r#"
3558# Should be ignored
3559meta arches["386", "amd64", "arm", "arm64"]
3560meta noextract
3561
3562abcd {
3563	a int32
3564}
3565
3566resource fd[int32]
3567syz_func(a fd)
3568fake(a fd)
3569fake(a ptr[in, abcd])
3570fake(a ptr[in, array[int32]])
3571		"#;
3572		let _p = Parsed::assemble(s2, s1, None).unwrap();
3573	}
3574
3575	#[test]
3576	fn single_const0() {
3577		let s1 = r#"arches = amd64"#;
3578		let s2 = r#"
3579abcd {
3580	a0 const[42, int32]
3581	a1 const["hello_world", string]
3582}
3583		"#;
3584		let _p = Parsed::assemble(s2, s1, None).unwrap();
3585	}
3586
3587	#[test]
3588	fn single_const1() {
3589		let s1 = r#"
3590# Code generated by syz-sysgen. DO NOT EDIT.
3591arches = 386, amd64, arm, arm64, mips64le, ppc64le, riscv64, s390x
3592ACL_EXECUTE = 1
3593AT_FDCWD = 18446744073709551516
3594__NR_lgetxattr = 9, 386:arm:230, amd64:192, mips64le:5184, ppc64le:213, s390x:228
3595		"#;
3596		let consts = Parsed::get_consts(s1, None).unwrap();
3597		let mut consts = Consts { consts };
3598		assert_eq!(consts.find_sysno("lgetxattr", &Arch::X86).unwrap(), 230);
3599		assert_eq!(consts.find_sysno("lgetxattr", &Arch::X86_64).unwrap(), 192);
3600		assert_eq!(consts.find_sysno("lgetxattr", &Arch::Riscv64).unwrap(), 9);
3601
3602		let _r = consts.find_name_arch("AT_FDCWD", &Arch::X86_64).unwrap();
3603
3604		let ins = Const::new("ACL_EXECUTE", Value::Int(1), vec![Arch::X86_64]);
3605		assert!(!consts.add_if_new(ins));
3606
3607		let ins = Const::new("SOME_OTHER_VAL", Value::Int(2), vec![Arch::X86_64]);
3608		assert_eq!(consts.add_vec(vec![ins]), 1);
3609	}
3610	#[test]
3611	fn single_const2() {
3612		let s1 = r#"
3613# Code generated by syz-sysgen. DO NOT EDIT.
3614arches = amd64
3615AT_FDCWD = ???
3616CONS_GETVERS = amd64:1074029386
3617KDDISABIO = amd64:536890173
3618		"#;
3619		let _consts = Parsed::get_consts(s1, None).unwrap();
3620	}
3621
3622	#[test]
3623	fn single_struct0() {
3624		let s1 = r#"arches = amd64"#;
3625		let s2 = r#"
3626type qwerty int32
3627type asdfgh int64[0:5, 8]
3628type zxcv[T] int32[T:100]
3629type hjkl[T,Y] int32[T:Y]
3630flagvals = 1, 42, 84
3631abcd {
3632	a0 qwerty
3633	a1 asdfgh
3634	a2 zxcv[9]
3635	a3 hjkl[1,5]
3636	a4 int64 (out_overlay)
3637	a5 ptr[in, int64]
3638	a6 ptr[out, int32],
3639	a7 buffer[out]
3640	a8 len[a7, intptr]
3641	a9 offsetof[a3, int32]
3642	aa ptr[in, string["abcd"]]
3643	ab ptr[in, text[target], opt]
3644	ac vma64
3645	ad proc[1, 100, int16]
3646	ae fmt[oct, int64]
3647	af array[int8, 16]
3648	b0 int32[0:2]
3649	b1 int32:12
3650	b2 flags[flagvals, int32]
3651	b3 ptr[in, glob["/sys/**/*:-/sys/power/state"]]
3652	b4 ptr[in, compressed_image]
3653	b5 fileoff[intptr]
3654} [packed]
3655
3656jkh [
3657	b0 intptr
3658	b1 int8
3659] [varlen]
3660		"#;
3661		let p = Parsed::assemble(s2, s1, None).unwrap();
3662		let _n = serde_json::to_string(&p).unwrap();
3663	}
3664
3665	#[test]
3666	fn single_resource0() {
3667		let s1 = r#"arches = amd64"#;
3668		let s2 = r#"
3669resource fd[int32]
3670resource afd[fd]: -1
3671
3672ioctl$BINDER_SET_CONTEXT_MGR_EXT(fd fd_binder, cmd const[BINDER_SET_CONTEXT_MGR_EXT], arg ptr[in, flat_binder_object_t[BINDER_TYPE_BINDER, binder_node]])
3673		"#;
3674		let p = Parsed::assemble(s2, s1, None).unwrap();
3675		let r = serde_json::to_value(&p).unwrap();
3676		let _r = serde_json::to_string(&r).unwrap();
3677	}
3678
3679	#[test]
3680	fn single_typealias0() {
3681		let s1 = r#"arches = amd64"#;
3682		let s2 = r#"
3683type bool32 int32[0:1]
3684		"#;
3685		let _p = Parsed::assemble(s2, s1, None).unwrap();
3686	}
3687
3688	#[test]
3689	fn single_flags0() {
3690		let s1 = r#"arches = amd64"#;
3691		let s2 = r#"
3692name1 = 1, 2, 4
3693name1 = 1,2,4
3694name2 = "hello"
3695name3 = "hello", "world", "!"
3696name4 = "hello","world","!"
3697name5 = "hello world"
3698		"#;
3699		let _p = Parsed::assemble(s2, s1, None).unwrap();
3700	}
3701
3702	#[test]
3703	fn single_typetemplate0() {
3704		let s1 = r#"arches = amd64"#;
3705		let s2 = r#"
3706type alignptr[T] {
3707	v   T
3708} [align[PTR_SIZE]]
3709
3710some_struct {
3711	a0 alignptr[int32]
3712	csum csum[tcp_packet, pseudo, IPPROTO_TCP, int16be]
3713}
3714		"#;
3715		let _p = Parsed::assemble(s2, s1, None).unwrap();
3716	}
3717
3718	#[test]
3719	fn single_syscall0() {
3720		let s1 = r#"
3721arches = amd64
3722__NR_fake1 = 1
3723		"#;
3724		let s2 = r#"
3725# Same function name, but different args is not allowed in Syzlang, but we
3726# don't care during testing
3727fake1()
3728fake1$sub() int32
3729fake1(val int64)
3730fake1(val const[0]) (timeout[3000], prog_timeout[3000])
3731fake1(addr vma)
3732		"#;
3733		let _p = Parsed::assemble(s2, s1, None).unwrap();
3734	}
3735
3736	#[test]
3737	fn single_define() {
3738		let s1 = r#"
3739arches = amd64
3740__NR_fake1 = 1
3741AT_FDCWD = 18446744073709551516
3742		"#;
3743		let s2 = r#"
3744define ABCD 1
3745"#;
3746		let _p = Parsed::assemble(s2, s1, None).unwrap();
3747	}
3748
3749	#[test]
3750	fn test_empty() {
3751		let consts = r#"
3752		"#;
3753		let stmts = r#"
3754		"#;
3755		let p = Parsed::assemble(stmts, consts, None).unwrap();
3756
3757		assert!(p.consts.consts.is_empty());
3758	}
3759
3760	#[test]
3761	fn test_arches() {
3762		let s = r#"arches = 386, amd64, arm, arm64, mips64le, ppc64le, riscv64, s390x
3763ADDR_COMPAT_LAYOUT = 2097152
3764ARCH_SHSTK_UNLOCK = 20484, arm:arm64:mips64le:ppc64le:riscv64:s390x:???
3765"#;
3766		let tokens = Token::create_from_str(s).unwrap();
3767		let _arches = Const::from_tokens(tokens, None).unwrap();
3768	}
3769
3770	#[test]
3771	fn test_statements() {
3772		let s = "include <asm/prctl.h>";
3773		let tokens = Token::create_from_str(s).unwrap();
3774		debug!("tokens: {tokens:?}");
3775		let stmts = Statement::from_tokens(tokens).unwrap();
3776		debug!("stmts: {stmts:?}");
3777
3778		let s = "resource fd[int32]: AT_FDCWD";
3779		let tokens = Token::create_from_str(s).unwrap();
3780		debug!("tokens: {tokens:?}");
3781		let stmts = Statement::from_tokens(tokens).unwrap();
3782		debug!("stmts: {stmts:?}");
3783
3784		let s = "resource gid[int32]: 0, -1, 0xee00, 0xee01";
3785		let tokens = Token::create_from_str(s).unwrap();
3786		debug!("tokens: {tokens:?}");
3787		let stmts = Statement::from_tokens(tokens).unwrap();
3788		debug!("stmts: {stmts:?}");
3789
3790		let s = "type signalno int32[0:65]";
3791		let tokens = Token::create_from_str(s).unwrap();
3792		let _stmts = Statement::from_tokens(tokens).unwrap();
3793
3794		let s = r#"type iovec[DIR, T] { 
3795			addr    ptr[DIR, T]
3796			len len[addr, intptr]
3797		}"#;
3798
3799		let tokens = Token::create_from_str(s).unwrap();
3800		debug!("tokens: {tokens:?}");
3801		let stmts = Statement::from_tokens(tokens).unwrap();
3802		debug!("stmts: {stmts:?}");
3803
3804		let s = "pkey_alloc(flags const[0]) pkey";
3805		let tokens = Token::create_from_str(s).unwrap();
3806		let _stmts = Statement::from_tokens(tokens).unwrap();
3807
3808		let s = r#"openat$sysfs(dir ptr[in, glob["/sys/**/*:-/sys/power/state"]]) fd"#;
3809		let tokens = Token::create_from_str(s).unwrap();
3810		let _stmts = Statement::from_tokens(tokens).unwrap();
3811
3812		let s = "readv(fd fd, vec ptr[in, array[iovec_out]], vlen len[vec])";
3813		let tokens = Token::create_from_str(s).unwrap();
3814		let _stmts = Statement::from_tokens(tokens).unwrap();
3815
3816		let s = "open(file ptr[in, filename], flags flags[open_flags], mode flags[open_mode]) fd";
3817		let tokens = Token::create_from_str(s).unwrap();
3818		let _stmts = Statement::from_tokens(tokens).unwrap();
3819
3820		let s = r#"rseq {
3821			cpu_id_start    const[0, int32]
3822			cpu_id      const[0, int32]
3823			rseq_cs     ptr64[in, rseq_cs, opt] 
3824			flags       flags[rseq_cs_flags, int32]
3825			int         int32 (in)
3826		} [align[32]]"#;
3827		let tokens = Token::create_from_str(s).unwrap();
3828		let _stmts = Statement::from_tokens(tokens).unwrap();
3829
3830		let s = r#"sigevent_u [
3831			tid pid
3832			thr sigevent_thread
3833		]"#;
3834		let tokens = Token::create_from_str(s).unwrap();
3835		let _stmts = Statement::from_tokens(tokens).unwrap();
3836
3837		let s = "fid_type = FILEID_ROOT, FILEID_INO32_GEN, FILEID_INO32_GEN_PARENT, FILEID_BTRFS_WITHOUT_PARENT, FILEID_BTRFS_WITH_PARENT, FILEID_BTRFS_WITH_PARENT_ROOT, FILEID_UDF_WITHOUT_PARENT, FILEID_UDF_WITH_PARENT, FILEID_NILFS_WITHOUT_PARENT, FILEID_NILFS_WITH_PARENT, FILEID_FAT_WITHOUT_PARENT, FILEID_FAT_WITH_PARENT, FILEID_LUSTRE, FILEID_KERNFS";
3838		let tokens = Token::create_from_str(s).unwrap();
3839		let _stmts = Statement::from_tokens(tokens).unwrap();
3840
3841		let s = "define SIGEVENT_SIZE    sizeof(struct sigevent)";
3842		let tokens = Token::create_from_str(s).unwrap();
3843		let _stmts = Statement::from_tokens(tokens).unwrap();
3844	}
3845}