1use 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#[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#[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#[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#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
187pub enum Value {
188 Int(i64),
190
191 String(String),
193
194 Ident(Identifier),
196
197 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 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 generror!(format!("Unable to parse {src}:{base} as Value"), warn)
231 }
232 }
233 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#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
340pub struct Const {
341 pub name: String,
343
344 pub value: Value,
346
347 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 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 pub fn name(&self) -> &str {
373 &self.name
374 }
375
376 pub fn value(&self) -> &Value {
378 &self.value
379 }
380
381 pub fn is_for_arch(&self, arch: &Arch) -> bool {
383 self.arch.contains(arch)
384 }
385
386 pub fn arches(&self) -> std::slice::Iter<'_, Arch> {
388 self.arch.iter()
389 }
390
391 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#[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 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 pub fn consts(&'_ self) -> std::slice::Iter<'_, Const> {
569 self.consts.iter()
570 }
571
572 pub fn push(&mut self, c: Const) {
574 self.consts.push(c)
575 }
576
577 pub fn find_name_arch(&self, name: &str, arch: &Arch) -> Option<&Const> {
579 self.consts
581 .iter()
582 .find(|&c| c.name == name && c.is_for_arch(arch))
583 }
584
585 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(); 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 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 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 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 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 pub fn filter_arch(&mut self, arch: &Arch) {
672 self.consts.retain(|x| x.arch.contains(arch));
673 }
674}
675
676#[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 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 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::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#[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#[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#[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 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 Tokens(Vec<Token>),
1034 Arch(Arch),
1035 ProcOpt(Value, Value),
1036}
1037
1038impl 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 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); 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 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#[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#[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 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 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 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 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 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 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 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 gen_get_ident! { name }
2111 gen_get_iter! { opts, ArgOpt }
2112 gen_get! { arg_type, argtype, ArgType }
2113
2114 pub fn direction(&self) -> Direction {
2116 ArgOpt::direction(&self.opts, &Direction::In)
2117 }
2118
2119 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 ret.push(curr);
2149 Ok(ret)
2150 }
2151}
2152
2153#[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 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#[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 }
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#[derive(Debug, Default, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
2227pub struct Identifier {
2228 pub name: String,
2229
2230 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}
2260impl 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#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2309pub struct Include {
2310 name: String,
2311 is_file: bool,
2312}
2313
2314impl Include {
2315 pub fn name(&self) -> &str {
2317 &self.name
2318 }
2319
2320 pub fn is_dir(&self) -> bool {
2322 !self.is_file
2323 }
2324
2325 pub fn is_file(&self) -> bool {
2327 self.is_file
2328 }
2329}
2330
2331#[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#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
2348pub enum CreateType {
2349 CreateUnion,
2350 CreateStruct,
2351 CreateEntity,
2352}
2353
2354#[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 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#[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 gen_get_ident! { name }
2413 gen_get_iter! { specials, consts, Value }
2414 gen_get! { arg_type, atype, ArgType }
2415}
2416
2417#[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 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 }
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#[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 }
2472
2473#[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#[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 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 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 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 if !tokens.is_empty() {
2735 let t = consume!(tokens); 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 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 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 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#[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#[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 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 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 pub fn identifier_to_ident_type(&self, ident: &Identifier) -> Option<&IdentType> {
3146 self.idtypes.get(ident)
3147 }
3148 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 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 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 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 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 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 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 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 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 pub fn clear_unneeded(&mut self) -> Result<()> {
3415 self.aliases.clear();
3416 self.templates.clear();
3417 self.idtypes.clear();
3418 Ok(())
3419 }
3420
3421 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}