1use super::attributes;
2use crate::call_stack::MemoryAccess;
3use crate::registers::Registers;
4use std::convert::TryInto;
5
6use gimli::{DwAte, Location, Piece, Reader};
7
8use anyhow::{anyhow, Result};
9use log::{debug, error, info};
10
11use std::fmt;
12
13#[derive(Debug, Clone)]
17struct MyPiece<R: Reader<Offset = usize>> {
18 pub piece: Piece<R>,
20
21 pub used_before: bool,
23}
24impl<R: Reader<Offset = usize>> MyPiece<R> {
25 pub fn new(piece: Piece<R>) -> MyPiece<R> {
27 MyPiece {
28 piece,
29 used_before: false,
30 }
31 }
32
33 pub fn should_remove(&mut self, bit_size: u64) -> bool {
40 match self.piece.size_in_bits {
41 Some(val) => {
42 if val > bit_size {
43 self.piece.size_in_bits = Some(val - bit_size);
44 self.used_before = true;
45 false
46 } else {
47 self.used_before = true;
48 self.piece.size_in_bits = Some(0);
49 true
50 }
51 }
52 None => {
53 self.used_before = true;
54 false
55 }
56 }
57 }
58}
59
60#[derive(Debug, Clone)]
62pub enum EvaluatorValue<R: Reader<Offset = usize>> {
63 Value(BaseTypeValue, ValueInformation),
65
66 PointerTypeValue(Box<PointerTypeValue<R>>),
68
69 VariantValue(Box<VariantValue<R>>),
71
72 VariantPartValue(Box<VariantPartValue<R>>),
74
75 SubrangeTypeValue(SubrangeTypeValue),
77
78 Bytes(R),
80
81 Array(Box<ArrayTypeValue<R>>),
83
84 Struct(Box<StructureTypeValue<R>>),
86
87 Enum(Box<EnumerationTypeValue<R>>),
89
90 Union(Box<UnionTypeValue<R>>),
92
93 Member(Box<MemberValue<R>>),
95
96 OptimizedOut, LocationOutOfRange,
102
103 ZeroSize,
105}
106
107impl<R: Reader<Offset = usize>> fmt::Display for EvaluatorValue<R> {
108 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109 match self {
110 EvaluatorValue::Value(val, _) => val.fmt(f),
111 EvaluatorValue::PointerTypeValue(pt) => pt.fmt(f),
112 EvaluatorValue::VariantValue(var) => var.fmt(f),
113 EvaluatorValue::VariantPartValue(vpa) => vpa.fmt(f),
114 EvaluatorValue::SubrangeTypeValue(srt) => srt.fmt(f),
115 EvaluatorValue::Bytes(byt) => write!(f, "{:?}", byt),
116 EvaluatorValue::Array(arr) => arr.fmt(f),
117 EvaluatorValue::Struct(stu) => stu.fmt(f),
118 EvaluatorValue::Enum(enu) => enu.fmt(f),
119 EvaluatorValue::Union(uni) => uni.fmt(f),
120 EvaluatorValue::Member(mem) => mem.fmt(f),
121 EvaluatorValue::OptimizedOut => write!(f, "< OptimizedOut >"),
122 EvaluatorValue::LocationOutOfRange => write!(f, "< LocationOutOfRange >"),
123 EvaluatorValue::ZeroSize => write!(f, "< ZeroSize >"),
124 }
125 }
126}
127
128impl<R: Reader<Offset = usize>> EvaluatorValue<R> {
129 pub fn to_value(self) -> Option<BaseTypeValue> {
131 match self {
132 EvaluatorValue::Value(val, _) => Some(val),
133 EvaluatorValue::Member(val) => val.value.to_value(),
134 EvaluatorValue::OptimizedOut => None,
135 EvaluatorValue::ZeroSize => None,
136 _ => None, }
138 }
139
140 pub fn get_type(&self) -> String {
142 match self {
143 EvaluatorValue::Value(val, _) => val.get_type(),
145 EvaluatorValue::Array(arr) => arr.get_type(),
146 EvaluatorValue::Struct(stu) => stu.get_type(),
147 EvaluatorValue::Enum(enu) => enu.get_type(),
148 EvaluatorValue::Union(uni) => uni.get_type(),
149 EvaluatorValue::Member(mem) => mem.get_type(),
150 _ => "<unknown>".to_owned(),
151 }
152 }
153
154 pub fn get_variable_information(self) -> Vec<ValueInformation> {
156 match self {
157 EvaluatorValue::Value(_, var_info) => vec![var_info],
158 EvaluatorValue::Array(arr) => {
159 let mut info = vec![];
160 for val in arr.values {
161 info.append(&mut val.get_variable_information());
162 }
163 info
164 }
165 EvaluatorValue::Struct(st) => {
166 let mut info = vec![];
167 for val in st.members {
168 info.append(&mut val.get_variable_information());
169 }
170 info
171 }
172 EvaluatorValue::Enum(en) => en.variant.get_variable_information(),
173 EvaluatorValue::Union(un) => {
174 let mut info = vec![];
175 for val in un.members {
176 info.append(&mut val.get_variable_information());
177 }
178 info
179 }
180 EvaluatorValue::Member(me) => me.value.get_variable_information(),
181 EvaluatorValue::OptimizedOut => {
182 vec![ValueInformation::new(
183 None,
184 vec![ValuePiece::Dwarf { value: None }],
185 )]
186 }
187 _ => vec![],
188 }
189 }
190
191 pub fn evaluate_variable_with_type<M: MemoryAccess>(
205 dwarf: &gimli::Dwarf<R>,
206 registers: &Registers,
207 mem: &mut M,
208 pieces: &[Piece<R>],
209 unit_offset: gimli::UnitSectionOffset,
210 die_offset: gimli::UnitOffset,
211 ) -> Result<EvaluatorValue<R>> {
212 log::info!("evaluate_variable_with_type");
213 let data_offset: u64 = 0;
215
216 let unit = match unit_offset {
218 gimli::UnitSectionOffset::DebugInfoOffset(offset) => {
219 let header = dwarf.debug_info.header_from_offset(offset)?;
220 dwarf.unit(header)?
221 }
222 gimli::UnitSectionOffset::DebugTypesOffset(_offset) => {
223 let mut iter = dwarf.debug_types.units();
224 let mut result = None;
225 while let Some(header) = iter.next()? {
226 if header.offset() == unit_offset {
227 result = Some(dwarf.unit(header)?);
228 break;
229 }
230 }
231 match result {
232 Some(val) => val,
233 None => {
234 error!("Could not find unit from offset");
235 return Err(anyhow!("Could not find unit from offset"));
236 }
237 }
238 }
239 };
240 info!("Found unit");
241
242 let die = &unit.entry(die_offset)?;
244 info!("Found die");
245
246 let mut my_pieces = pieces.iter().map(|p| MyPiece::new(p.clone())).collect();
247 info!("has pieces");
248
249 EvaluatorValue::eval_type(
251 registers,
252 mem,
253 dwarf,
254 &unit,
255 die,
256 data_offset,
257 &mut my_pieces,
258 )
259 }
260
261 pub fn evaluate_variable<M: MemoryAccess>(
269 registers: &Registers,
270 mem: &mut M,
271 pieces: &[Piece<R>],
272 ) -> Result<EvaluatorValue<R>> {
273 log::debug!("evaluate_variable");
274 let mut my_pieces = pieces.iter().map(|p| MyPiece::new(p.clone())).collect();
275 EvaluatorValue::handle_eval_piece(registers, mem, 4, 0, DwAte(1), &mut my_pieces)
276 }
277
278 fn handle_eval_piece<M: MemoryAccess>(
289 registers: &Registers,
290 mem: &mut M,
291 byte_size: u64,
292 data_offset: u64,
293 encoding: DwAte,
294 pieces: &mut Vec<MyPiece<R>>,
295 ) -> Result<EvaluatorValue<R>> {
296 debug!("encoding: {:?}", encoding);
297 debug!("byte_size: {:?}", byte_size);
298 debug!("pieces: {:?}", pieces);
299 if pieces.is_empty() {
300 return Ok(EvaluatorValue::OptimizedOut);
301 }
302
303 let mut all_bytes = vec![];
304 let mut value_pieces = vec![];
305 while all_bytes.len() < byte_size.try_into()? {
306 if pieces.is_empty() {
307 error!("Unreachable");
308 return Err(anyhow!("Unreachable"));
309 }
311
312 match pieces[0].piece.clone().location {
314 Location::Empty => {
315 let bit_size = 8 * (byte_size - all_bytes.len() as u64);
317 if pieces[0].should_remove(bit_size) {
318 pieces.remove(0);
319 }
320 return Ok(EvaluatorValue::OptimizedOut);
321 }
322 Location::Register { ref register } => {
323 match registers.get_register_value(®ister.0) {
324 Some(val) => {
325 let mut bytes = vec![];
327 bytes.extend_from_slice(&val.to_le_bytes());
328
329 bytes = trim_piece_bytes(bytes, &pieces[0].piece, 4); let bytes_len = bytes.len();
331
332 all_bytes.extend_from_slice(&bytes);
333 value_pieces.extend_from_slice(&[ValuePiece::Register {
334 register: register.0,
335 byte_size: bytes_len,
336 }]);
337
338 let bit_size = 8 * (bytes_len as u64);
340 if pieces[0].should_remove(bit_size) {
341 pieces.remove(0);
342 }
343 }
344 None => return Err(anyhow!("Requires reg")),
345 };
346 }
347 Location::Address { mut address } => {
348 address += {
350 if pieces[0].used_before {
351 data_offset
352 } else {
353 0
354 }
355 };
356
357 let num_bytes = match pieces[0].piece.size_in_bits {
358 Some(val) => {
359 let max_num_bytes = (val + 8 - 1) / 8;
360 let needed_num_bytes = byte_size - all_bytes.len() as u64;
361 if max_num_bytes < needed_num_bytes {
362 max_num_bytes
363 } else {
364 needed_num_bytes
365 }
366 }
367 None => byte_size - all_bytes.len() as u64,
368 } as usize;
369
370 let bytes = match mem.get_address(&(address as u32), num_bytes) {
371 Some(val) => val,
372 None => {
373 error!(
374 "can not read address: {:x} num_bytes: {:?}, Return error",
375 address as u64, num_bytes
376 );
377 return Err(anyhow!(
378 "can not read address: {:x} num_bytes: {:?}, Return error",
379 address as u64,
380 num_bytes
381 ));
382 }
383 };
384
385 all_bytes.extend_from_slice(&bytes);
386 value_pieces.extend_from_slice(&[ValuePiece::Memory {
387 address: address as u32,
388 byte_size: num_bytes,
389 }]);
390
391 let bit_size = 8 * num_bytes as u64;
393 if pieces[0].should_remove(bit_size) {
394 pieces.remove(0);
395 }
396 }
397 Location::Value { value } => {
398 let bit_size = 8 * (byte_size - all_bytes.len() as u64);
400 if pieces[0].should_remove(bit_size) {
401 pieces.remove(0);
402 }
403
404 let parsed_value = convert_from_gimli_value(value);
405 return match parsed_value {
406 BaseTypeValue::Generic(v) => {
407 let correct_value = match (encoding, byte_size) {
408 (DwAte(1), 4) => BaseTypeValue::Address32(v as u32),
409 (DwAte(2), _) => BaseTypeValue::Bool(v != 0),
411 (DwAte(7), 1) => BaseTypeValue::U8(v as u8),
412 (DwAte(7), 2) => BaseTypeValue::U16(v as u16),
413 (DwAte(7), 4) => BaseTypeValue::U32(v as u32),
414 (DwAte(7), 8) => BaseTypeValue::U64(v as u64),
415 (DwAte(5), 1) => BaseTypeValue::I8(v as i8),
416 (DwAte(5), 2) => BaseTypeValue::I16(v as i16),
417 (DwAte(5), 4) => BaseTypeValue::I32(v as i32),
418 (DwAte(5), 8) => BaseTypeValue::I64(v as i64),
419 (DwAte(4), 4) => BaseTypeValue::F32(v as f32),
420 (DwAte(4), 8) => BaseTypeValue::F64(v as f64),
421 _ => BaseTypeValue::Generic(v),
422 };
423 Ok(EvaluatorValue::Value(
425 correct_value,
426 ValueInformation::new(
427 None,
428 vec![ValuePiece::Dwarf { value: Some(value) }],
429 ),
430 ))
431 }
432 _ => Ok(EvaluatorValue::Value(
433 parsed_value,
434 ValueInformation {
435 raw: None,
436 pieces: vec![ValuePiece::Dwarf { value: Some(value) }],
437 },
438 )),
439 };
440 }
441
442 Location::Bytes { mut value } => {
443 let mut bytes = vec![];
444 let mut loops = byte_size as usize - all_bytes.len();
445 if value.len() < loops {
446 loops = value.len();
447 }
448 for _i in 0..loops {
449 bytes.push(value.read_u8()?);
450 }
451
452 value_pieces.extend_from_slice(&[ValuePiece::Bytes {
453 bytes: bytes.clone(),
454 }]);
455
456 all_bytes.extend_from_slice(&bytes.into_boxed_slice());
457
458 let bit_size = 8 * (byte_size - all_bytes.len() as u64);
460 if pieces[0].should_remove(bit_size) {
461 pieces.remove(0);
462 }
463
464 }
466 Location::ImplicitPointer {
467 value: _,
468 byte_offset: _,
469 } => {
470 error!("Unimplemented");
471 return Err(anyhow!("Unimplemented"));
472 }
473 }
474 }
475
476 while all_bytes.len() > byte_size as usize {
477 all_bytes.pop(); }
479
480 Ok(EvaluatorValue::Value(
481 BaseTypeValue::parse_base_type(all_bytes.clone(), encoding)?,
482 ValueInformation::new(Some(all_bytes.clone()), value_pieces),
483 ))
484 }
485
486 fn eval_type<M: MemoryAccess>(
498 registers: &Registers,
499 mem: &mut M,
500 dwarf: &gimli::Dwarf<R>,
501 unit: &gimli::Unit<R>,
502 die: &gimli::DebuggingInformationEntry<'_, '_, R>,
503 data_offset: u64,
504 pieces: &mut Vec<MyPiece<R>>,
505 ) -> Result<EvaluatorValue<R>> {
506 info!("tag: {:?}", die.tag());
507 match die.tag() {
508 gimli::DW_TAG_base_type => {
509 match die.tag() {
511 gimli::DW_TAG_base_type => (),
512 _ => {
513 error!("Expected DW_TAG_base_type die, this should never happen");
514 return Err(anyhow!(
515 "Expected DW_TAG_base_type die, this should never happen"
516 ));
517 }
518 };
519
520 check_alignment(die, data_offset, pieces)?;
521
522 let byte_size = match attributes::byte_size_attribute(die)? {
524 Some(val) => val,
525 None => {
526 error!("Missing required byte size attribute");
527 return Err(anyhow!("Missing required byte size attribute"));
528 }
529 };
530
531 if byte_size == 0 {
532 return Ok(EvaluatorValue::ZeroSize);
533 }
534
535 let encoding = match attributes::encoding_attribute(die)? {
536 Some(val) => val,
537 None => {
538 error!("Missing required encoding attribute");
539 return Err(anyhow!("Missing required encoding attribute"));
540 }
541 };
542
543 EvaluatorValue::handle_eval_piece(
545 registers,
546 mem,
547 byte_size,
548 data_offset, encoding,
550 pieces,
551 )
552 }
553 gimli::DW_TAG_pointer_type => {
554 info!("DW_TAG_pointer_type");
555 match die.tag() {
557 gimli::DW_TAG_pointer_type => (),
558 _ => {
559 error!("Expected DW_TAG_pointer_type die, this should never happen");
560 return Err(anyhow!(
561 "Expected DW_TAG_pointer_type die, this should never happen"
562 ));
563 }
564 };
565
566 check_alignment(die, data_offset, pieces)?;
567
568 let name = attributes::name_attribute(dwarf, die)?;
570
571 let address_class = match attributes::address_class_attribute(die)? {
573 Some(val) => val,
574 None => {
575 error!("Die is missing required attribute DW_AT_address_class");
576 return Err(anyhow!(
577 "Die is missing required attribute DW_AT_address_class"
578 ));
579 }
580 };
581
582 let address = match address_class.0 {
584 0 => {
585 EvaluatorValue::handle_eval_piece(
586 registers,
587 mem,
588 4, data_offset,
590 DwAte(1),
591 pieces,
592 )?
593 }
594 _ => {
595 error!("Unimplemented DwAddr code"); return Err(anyhow!("Unimplemented DwAddr code"));
597 }
598 };
599
600 let value = match (attributes::type_attribute(dwarf, unit, die)?, &address) {
601 (
602 Some((section_offset, unit_offset)),
603 EvaluatorValue::Value(BaseTypeValue::Address32(address_value), _),
604 ) => {
605 let header = dwarf.debug_info.header_from_offset(
607 match section_offset.as_debug_info_offset() {
608 Some(val) => val,
609 None => {
610 error!(
611 "Could not convert section offset into debug info offset"
612 );
613 return Err(anyhow!(
614 "Could not convert section offset into debug info offset"
615 ));
616 }
617 },
618 )?;
619
620 let type_unit = gimli::Unit::new(dwarf, header)?;
621 let type_die = type_unit.entry(unit_offset)?;
622 let mut new_pieces = vec![MyPiece::new(Piece {
623 size_in_bits: None,
624 bit_offset: None,
625 location: Location::<R>::Address {
626 address: *address_value as u64,
627 },
628 })];
629 EvaluatorValue::eval_type(
630 registers,
631 mem,
632 dwarf,
633 &type_unit,
634 &type_die,
635 0,
636 &mut new_pieces,
637 )?
638 }
639 _ => EvaluatorValue::OptimizedOut,
640 };
641
642 Ok(EvaluatorValue::PointerTypeValue(Box::new(
643 PointerTypeValue {
644 name,
645 address,
646 value,
647 },
648 )))
649
650 }
652 gimli::DW_TAG_array_type => {
653 match die.tag() {
655 gimli::DW_TAG_array_type => (),
656 _ => {
657 error!("Expected DW_TAG_array_type die, this should never happen");
658 return Err(anyhow!(
659 "Expected DW_TAG_array_type die, this should never happen"
660 ));
661 }
662 };
663
664 check_alignment(die, data_offset, pieces)?;
665
666 let mut children = get_children(unit, die)?;
667 let mut i = 0;
668 while i < children.len() {
669 let die = unit.entry(children[i])?;
670 match die.tag() {
671 gimli::DW_TAG_subrange_type => (),
672 _ => {
673 let _c = children.remove(i);
674 i -= 1;
675 }
676 }
677 i += 1;
678 }
679
680 if children.len() != 1 {
681 error!("Unreachable");
682 return Err(anyhow!("Unreachable"));
683 }
684
685 let dimension_die = unit.entry(children[0])?;
686
687 let subrange_type_value = match EvaluatorValue::eval_type(
688 registers,
689 mem,
690 dwarf,
691 unit,
692 &dimension_die,
693 data_offset,
694 pieces,
695 )? {
696 EvaluatorValue::SubrangeTypeValue(subrange_type_value) => subrange_type_value,
697 _ => {
698 error!("Unreachable");
699 return Err(anyhow!("Unreachable"));
700 }
701 };
702
703 let mut values = vec![];
704
705 match subrange_type_value.get_count()? {
707 Some(count) => {
708 let (type_unit, die_offset) = get_type_info(dwarf, unit, die)?;
710 let type_die = &type_unit.entry(die_offset)?;
711
712 for _i in 0..count {
714 values.push(EvaluatorValue::eval_type(
715 registers,
716 mem,
717 dwarf,
718 &type_unit,
719 type_die,
720 data_offset,
721 pieces,
722 )?);
723 }
724 }
725 None => (),
726 };
727
728 Ok(EvaluatorValue::Array(Box::new(ArrayTypeValue {
729 subrange_type_value,
730 values,
731 })))
732 }
733 gimli::DW_TAG_structure_type => {
734 match die.tag() {
736 gimli::DW_TAG_structure_type => (),
737 _ => {
738 error!("Expected DW_TAG_structure_type die, this should never happen");
739 return Err(anyhow!(
740 "Expected DW_TAG_structure_type die, this should never happen"
741 ));
742 }
743 };
744
745 check_alignment(die, data_offset, pieces)?;
746
747 let name = match attributes::name_attribute(dwarf, die)? {
748 Some(val) => val,
749 None => {
750 error!("Expected the structure type die to have a name attribute");
751 return Err(anyhow!(
752 "Expected the structure type die to have a name attribute"
753 ));
754 }
755 };
756
757 let children = get_children(unit, die)?;
759 let mut member_dies = Vec::new();
760 for c in &children {
761 let c_die = unit.entry(*c)?;
762 match c_die.tag() {
763 gimli::DW_TAG_variant_part => {
765 let members = vec![EvaluatorValue::eval_type(
767 registers,
768 mem,
769 dwarf,
770 unit,
771 &c_die,
772 data_offset,
773 pieces,
774 )?];
775
776 return Ok(EvaluatorValue::Struct(Box::new(StructureTypeValue {
777 name,
778 members,
779 })));
780 }
781 gimli::DW_TAG_member => {
782 let data_member_location =
783 match attributes::data_member_location_attribute(&c_die)? {
784 Some(val) => val,
785 None => {
786 error!(
787 "Expected member die to have attribute DW_AT_data_member_location"
788 );
789 return Err(
790 anyhow!(
791 "Expected member die to have attribute DW_AT_data_member_location"),
792 );
793 }
794 };
795 member_dies.push((data_member_location, c_die))
796 }
797 _ => continue,
798 };
799 }
800
801 member_dies.sort_by_key(|m| m.0);
803
804 let mut members = vec![];
806 for member_die in &member_dies {
807 let member = match member_die.1.tag() {
808 gimli::DW_TAG_member => EvaluatorValue::eval_type(
809 registers,
810 mem,
811 dwarf,
812 unit,
813 &member_die.1,
814 data_offset,
815 pieces,
816 )?,
817 tag => {
818 error!("Unexpected die tag: {:?}", tag);
819 return Err(anyhow!("Unimplemented"));
820 }
821 };
822 members.push(member);
823 }
824
825 Ok(EvaluatorValue::Struct(Box::new(StructureTypeValue {
826 name,
827 members,
828 })))
829 }
830 gimli::DW_TAG_union_type => {
831 match die.tag() {
833 gimli::DW_TAG_union_type => (),
834 _ => {
835 error!("Expected DW_TAG_union_type die, this should never happen");
836 return Err(anyhow!(
837 "Expected DW_TAG_union_type die, this should never happen"
838 ));
839 }
840 };
841
842 check_alignment(die, data_offset, pieces)?;
843
844 let name = match attributes::name_attribute(dwarf, die)? {
845 Some(val) => val,
846 None => {
847 error!("Expected union type die to have a name attribute");
848 return Err(anyhow!("Expected union type die to have a name attribute"));
849 }
850 };
851
852 let children = get_children(unit, die)?;
854 let mut member_dies = vec![];
855 for c in children {
856 let c_die = unit.entry(c)?;
857 match c_die.tag() {
858 gimli::DW_TAG_member => {
859 let data_member_location =
860 match attributes::data_member_location_attribute(&c_die)? {
861 Some(val) => val,
862 None => {
863 error!("Expected member die to have attribute DW_AT_data_member_location");
864 return Err(anyhow!("Expected member die to have attribute DW_AT_data_member_location"));
865 }
866 };
867 member_dies.push((data_member_location, c_die))
868 }
869 _ => continue,
870 };
871 }
872
873 member_dies.sort_by_key(|m| m.0);
875
876 let mut members = vec![];
878 for member_die in &member_dies {
879 let member = match member_die.1.tag() {
880 gimli::DW_TAG_member => EvaluatorValue::eval_type(
881 registers,
882 mem,
883 dwarf,
884 unit,
885 &member_die.1,
886 data_offset,
887 pieces,
888 )?,
889 tag => {
890 error!("Unexpected die with tag {:?}", tag);
891 return Err(anyhow!("Unimplemented"));
892 }
893 };
894 members.push(member);
895 }
896
897 Ok(EvaluatorValue::Union(Box::new(UnionTypeValue {
898 name,
899 members,
900 })))
901 }
902 gimli::DW_TAG_member => {
903 match die.tag() {
905 gimli::DW_TAG_member => (),
906 _ => {
907 error!("Expected DW_TAG_member die, this should never happen");
908 return Err(anyhow!(
909 "Expected DW_TAG_member die, this should never happen"
910 ));
911 }
912 };
913
914 let name = attributes::name_attribute(dwarf, die)?;
916
917 let new_data_offset = match attributes::data_member_location_attribute(die)? {
919 Some(val) => data_offset + val,
921 None => data_offset,
922 };
923
924 check_alignment(die, new_data_offset, pieces)?;
925
926 let (type_unit, die_offset) = get_type_info(dwarf, unit, die)?;
928 let type_die = &type_unit.entry(die_offset)?;
929
930 let value = EvaluatorValue::eval_type(
932 registers,
933 mem,
934 dwarf,
935 &type_unit,
936 type_die,
937 new_data_offset,
938 pieces,
939 )?;
940
941 Ok(EvaluatorValue::Member(Box::new(MemberValue {
942 name,
943 value,
944 })))
945 }
946 gimli::DW_TAG_enumeration_type => {
947 match die.tag() {
949 gimli::DW_TAG_enumeration_type => (),
950 _ => {
951 error!("Expected DW_TAG_enumeration_type die, this should never happen");
952 return Err(anyhow!(
953 "Expected DW_TAG_enumeration_type die, this should never happen"
954 ));
955 }
956 };
957
958 check_alignment(die, data_offset, pieces)?;
959
960 let (type_unit, die_offset) = get_type_info(dwarf, unit, die)?;
962 let type_die = &type_unit.entry(die_offset)?;
963
964 let variant = EvaluatorValue::eval_type(
966 registers,
967 mem,
968 dwarf,
969 &type_unit,
970 type_die,
971 data_offset,
972 pieces,
973 )?;
974
975 let children = get_children(unit, die)?;
977
978 let mut enumerators = vec![];
979 for c in children {
980 let c_die = unit.entry(c)?;
981 match c_die.tag() {
982 gimli::DW_TAG_enumerator => {
983 let name = attributes::name_attribute(dwarf, &c_die)?;
984
985 let const_value = match attributes::const_value_attribute(&c_die)? {
986 Some(val) => val,
987 None => {
988 error!("Expected enumeration type die to have attribute DW_AT_const_value");
989 return Err(anyhow!("Expected enumeration type die to have attribute DW_AT_const_value"));
990 }
991 };
992
993 enumerators.push(EnumeratorValue { name, const_value });
994 }
995 gimli::DW_TAG_subprogram => (),
996 tag => {
997 error!("Unimplemented for tag: {:?}", tag);
998 return Err(anyhow!("Unimplemented"));
999 }
1000 };
1001 }
1002
1003 let name = match attributes::name_attribute(dwarf, die)? {
1005 Some(val) => val,
1006 None => {
1007 error!("Expected enumeration type die to have attribute DW_AT_name");
1008 return Err(anyhow!(
1009 "Expected enumeration type die to have attribute DW_AT_name"
1010 ));
1011 }
1012 };
1013
1014 Ok(EvaluatorValue::Enum(Box::new(EnumerationTypeValue {
1015 name,
1016 variant,
1017 enumerators,
1018 })))
1019 }
1020 gimli::DW_TAG_variant_part => {
1021 match die.tag() {
1023 gimli::DW_TAG_variant_part => (),
1024 _ => {
1025 error!("Expected DW_TAG_variant_part die, this should never happen");
1026 return Err(anyhow!(
1027 "Expected DW_TAG_variant_part die, this should never happen"
1028 ));
1029 }
1030 };
1031
1032 check_alignment(die, data_offset, pieces)?;
1033
1034 let variant: Option<MemberValue<R>> = match attributes::discr_attribute(die)? {
1039 Some(die_offset) => {
1040 let member_die = &unit.entry(die_offset)?;
1041
1042 match member_die.tag() {
1044 gimli::DW_TAG_member => match EvaluatorValue::eval_type(
1045 registers,
1046 mem,
1047 dwarf,
1048 unit,
1049 member_die,
1050 data_offset,
1051 pieces,
1052 )? {
1053 EvaluatorValue::Member(member) => Some(*member),
1054 _ => {
1055 error!("Unreachable");
1056 return Err(anyhow!("Unreachable"));
1057 }
1058 },
1059 _ => {
1060 error!("Unreachable");
1061 return Err(anyhow!("Unreachable"));
1062 }
1063 }
1064 }
1065 None => None,
1066 };
1067
1068 let variant_number = match variant.clone() {
1070 Some(MemberValue { name: _name, value }) => match value.to_value() {
1071 Some(val) => Some(get_udata(val)?),
1072 None => None,
1073 },
1074 None => None,
1075 };
1076
1077 let original_pieces = pieces.clone();
1078 let mut variants = vec![];
1080 let children = get_children(unit, die)?;
1081 for c in &children {
1082 let c_die = unit.entry(*c)?;
1083 if c_die.tag() == gimli::DW_TAG_variant {
1084 let mut temp_pieces = original_pieces.clone();
1085 let variant = match EvaluatorValue::eval_type(
1087 registers,
1088 mem,
1089 dwarf,
1090 unit,
1091 &c_die,
1092 data_offset,
1093 &mut temp_pieces,
1094 )? {
1095 EvaluatorValue::VariantValue(variant) => variant,
1096 _ => {
1097 error!("Unreachable");
1098 return Err(anyhow!("Unreachable"));
1099 }
1100 };
1101
1102 if let (Some(discr_value), Some(variant_num)) =
1103 (variant.discr_value, variant_number)
1104 {
1105 if discr_value == variant_num {
1107 *pieces = temp_pieces;
1108 }
1109 };
1110
1111 variants.push(*variant);
1112 };
1113 }
1114
1115 Ok(EvaluatorValue::VariantPartValue(Box::new(
1116 VariantPartValue { variant, variants },
1117 )))
1118 }
1119 gimli::DW_TAG_variant => {
1120 check_alignment(die, data_offset, pieces)?;
1121
1122 let mut members = vec![];
1123
1124 let children = get_children(unit, die)?;
1126 for c in children {
1127 let c_die = unit.entry(c)?;
1128 if c_die.tag() == gimli::DW_TAG_member {
1129 let member = match EvaluatorValue::eval_type(
1131 registers,
1132 mem,
1133 dwarf,
1134 unit,
1135 &c_die,
1136 data_offset,
1137 pieces,
1138 )? {
1139 EvaluatorValue::Member(member) => member,
1140 _ => {
1141 error!("Unreachable");
1142 return Err(anyhow!("Unreachable"));
1143 }
1144 };
1145
1146 members.push(member);
1147 };
1148 }
1149
1150 if members.len() != 1 {
1151 error!("Unreachable");
1152 return Err(anyhow!("Unreachable"));
1153 }
1155
1156 let discr_value = attributes::discr_value_attribute(die)?;
1157
1158 Ok(EvaluatorValue::VariantValue(Box::new(VariantValue {
1159 discr_value,
1160 child: *members[0].clone(),
1161 })))
1162 }
1163 gimli::DW_TAG_subrange_type => {
1164 match die.tag() {
1166 gimli::DW_TAG_subrange_type => (),
1167 _ => {
1168 error!("Expected DW_TAG_subrange_type die, this should never happen");
1169 return Err(anyhow!(
1170 "Expected DW_TAG_subrange_type die, this should never happen"
1171 ));
1172 }
1173 };
1174
1175 let lower_bound = attributes::lower_bound_attribute(die)?;
1176
1177 match attributes::count_attribute(die)? {
1179 Some(count) => Ok(EvaluatorValue::SubrangeTypeValue(SubrangeTypeValue {
1181 lower_bound,
1182 count: Some(count),
1183 base_type_value: None,
1184 })),
1185 None => {
1186 let (type_unit, die_offset) = match get_type_info(dwarf, unit, die) {
1188 Ok(val) => val,
1189 Err(_) => {
1190 error!("Expected subrange type die to have type information");
1191 return Err(anyhow!(
1192 "Expected subrange type die to have type information"
1193 ));
1194 }
1195 };
1196 let type_die = &type_unit.entry(die_offset)?;
1197
1198 let base_type_value = match EvaluatorValue::eval_type(
1200 registers,
1201 mem,
1202 dwarf,
1203 &type_unit,
1204 type_die,
1205 data_offset,
1206 pieces,
1207 )? {
1208 EvaluatorValue::Value(base_type_value, value_information) => {
1209 Some((base_type_value, value_information))
1210 }
1211 _ => {
1212 error!("Unreachable");
1213 return Err(anyhow!("Unreachable"));
1214 }
1215 };
1216 Ok(EvaluatorValue::SubrangeTypeValue(SubrangeTypeValue {
1217 lower_bound,
1218 count: None,
1219 base_type_value,
1220 }))
1221 }
1222 }
1223 }
1224 gimli::DW_TAG_subroutine_type => {
1225 error!("Unimplemented");
1226 Err(anyhow!("Unimplemented"))
1227 }
1228 gimli::DW_TAG_subprogram => {
1229 error!("Unimplemented");
1230 Err(anyhow!("Unimplemented"))
1231 }
1232 gimli::DW_TAG_string_type => {
1233 error!("Unimplemented");
1234 Err(anyhow!("Unimplemented"))
1235 }
1236 gimli::DW_TAG_generic_subrange => {
1237 error!("Unimplemented");
1238 Err(anyhow!("Unimplemented"))
1239 }
1240 gimli::DW_TAG_template_type_parameter => {
1241 error!("Unimplemented");
1242 Err(anyhow!("Unimplemented"))
1243 }
1244 tag => {
1245 error!("Unimplemented for tag {:?}", tag);
1246 Err(anyhow!("Unimplemented"))
1247 }
1248 }
1249 }
1250}
1251
1252pub fn get_udata(value: BaseTypeValue) -> Result<u64> {
1258 match value {
1259 BaseTypeValue::U8(v) => Ok(v as u64),
1260 BaseTypeValue::U16(v) => Ok(v as u64),
1261 BaseTypeValue::U32(v) => Ok(v as u64),
1262 BaseTypeValue::U64(v) => Ok(v),
1263 BaseTypeValue::Generic(v) => Ok(v),
1264 _ => {
1265 error!("Unimplemented");
1266 Err(anyhow!("Unimplemented"))
1267 }
1268 }
1269}
1270
1271fn format_values<R: Reader<Offset = usize>>(values: &Vec<EvaluatorValue<R>>) -> String {
1277 let len = values.len();
1278 if len == 0 {
1279 return "".to_string();
1280 } else if len == 1 {
1281 return format!("{}", values[0]);
1282 }
1283
1284 let mut res = format!("{}", values[0]);
1285 for value in values.iter().take(len).skip(1) {
1286 res = format!("{}, {}", res, value);
1287 }
1288 res
1289}
1290
1291fn format_types<R: Reader<Offset = usize>>(values: &Vec<EvaluatorValue<R>>) -> String {
1297 let len = values.len();
1298 if len == 0 {
1299 return "".to_string();
1300 } else if len == 1 {
1301 return values[0].get_type();
1302 }
1303
1304 let mut res = values[0].get_type();
1305 for value in values.iter().take(len).skip(1) {
1306 res = format!("{}, {}", res, value.get_type());
1307 }
1308 res
1309}
1310
1311#[derive(Debug, Clone)]
1313pub struct ArrayTypeValue<R: Reader<Offset = usize>> {
1314 pub subrange_type_value: SubrangeTypeValue,
1316
1317 pub values: Vec<EvaluatorValue<R>>,
1319}
1320
1321impl<R: Reader<Offset = usize>> fmt::Display for ArrayTypeValue<R> {
1322 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1323 write!(f, "[ {} ]", format_values(&self.values))
1324 }
1325}
1326
1327impl<R: Reader<Offset = usize>> ArrayTypeValue<R> {
1328 pub fn get_type(&self) -> String {
1330 format!("[ {} ]", format_types(&self.values))
1331 }
1332}
1333
1334#[derive(Debug, Clone)]
1336pub struct StructureTypeValue<R: Reader<Offset = usize>> {
1337 pub name: String,
1339
1340 pub members: Vec<EvaluatorValue<R>>,
1342}
1343
1344impl<R: Reader<Offset = usize>> fmt::Display for StructureTypeValue<R> {
1345 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1346 write!(f, "{} {{ {} }}", self.name, format_values(&self.members))
1347 }
1348}
1349
1350impl<R: Reader<Offset = usize>> StructureTypeValue<R> {
1351 pub fn get_type(&self) -> String {
1353 format!("{} {{ {} }}", self.name, format_types(&self.members))
1354 }
1355}
1356
1357#[derive(Debug, Clone)]
1359pub struct EnumerationTypeValue<R: Reader<Offset = usize>> {
1360 pub name: String,
1362
1363 pub variant: EvaluatorValue<R>,
1365
1366 pub enumerators: Vec<EnumeratorValue>,
1368}
1369
1370impl<R: Reader<Offset = usize>> fmt::Display for EnumerationTypeValue<R> {
1371 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1372 write!(f, "{}::{}", self.name, self.variant)
1373 }
1374}
1375
1376impl<R: Reader<Offset = usize>> EnumerationTypeValue<R> {
1377 pub fn get_type(&self) -> String {
1379 format!("{}::{}", self.name, self.variant.get_type())
1380 }
1381}
1382
1383#[derive(Debug, Clone)]
1385pub struct UnionTypeValue<R: Reader<Offset = usize>> {
1386 pub name: String,
1388
1389 pub members: Vec<EvaluatorValue<R>>,
1391}
1392
1393impl<R: Reader<Offset = usize>> fmt::Display for UnionTypeValue<R> {
1394 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1395 write!(f, "{} ( {} )", self.name, format_values(&self.members))
1396 }
1397}
1398
1399impl<R: Reader<Offset = usize>> UnionTypeValue<R> {
1400 pub fn get_type(&self) -> String {
1402 format!("{} ( {} )", self.name, format_types(&self.members))
1403 }
1404}
1405
1406#[derive(Debug, Clone)]
1408pub struct MemberValue<R: Reader<Offset = usize>> {
1409 pub name: Option<String>,
1411
1412 pub value: EvaluatorValue<R>,
1414}
1415
1416impl<R: Reader<Offset = usize>> fmt::Display for MemberValue<R> {
1417 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1418 match &self.name {
1419 Some(name) => write!(f, "{}::{}", name, self.value),
1420 None => write!(f, "{}", self.value),
1421 }
1422 }
1423}
1424
1425impl<R: Reader<Offset = usize>> MemberValue<R> {
1426 pub fn get_type(&self) -> String {
1428 match &self.name {
1429 Some(name) => format!("{}::{}", name, self.value.get_type()),
1430 None => self.value.get_type(),
1431 }
1432 }
1433}
1434
1435#[derive(Debug, Clone)]
1437pub struct PointerTypeValue<R: Reader<Offset = usize>> {
1438 pub name: Option<String>,
1440
1441 pub address: EvaluatorValue<R>,
1443
1444 pub value: EvaluatorValue<R>,
1446 }
1451
1452impl<R: Reader<Offset = usize>> fmt::Display for PointerTypeValue<R> {
1453 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1454 match &self.name {
1455 Some(name) => write!(f, "{}::{}", name, self.value),
1456 None => write!(f, "{}", self.value),
1457 }
1458 }
1459}
1460
1461impl<R: Reader<Offset = usize>> PointerTypeValue<R> {
1462 pub fn get_type(&self) -> String {
1464 match &self.name {
1465 Some(name) => format!("{}::{}", name, self.value.get_type()),
1466 None => self.value.get_type(),
1467 }
1468 }
1469}
1470
1471#[derive(Debug, Clone)]
1473pub struct EnumeratorValue {
1474 pub name: Option<String>,
1476
1477 pub const_value: u64,
1479 }
1483
1484impl fmt::Display for EnumeratorValue {
1485 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1486 match &self.name {
1487 Some(name) => write!(f, "{}::{}", name, self.const_value),
1488 None => write!(f, "{}", self.const_value),
1489 }
1490 }
1491}
1492
1493impl EnumeratorValue {
1494 pub fn get_type(&self) -> String {
1496 format!("{:?}", self.name)
1497 }
1498}
1499
1500#[derive(Debug, Clone)]
1502pub struct VariantValue<R: Reader<Offset = usize>> {
1503 pub discr_value: Option<u64>,
1505
1506 pub child: MemberValue<R>,
1508 }
1512
1513impl<R: Reader<Offset = usize>> fmt::Display for VariantValue<R> {
1514 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1515 match &self.discr_value {
1516 Some(discr) => write!(f, "{}::{}", discr, self.child),
1517 None => write!(f, "{}", self.child),
1518 }
1519 }
1520}
1521
1522impl<R: Reader<Offset = usize>> VariantValue<R> {
1523 pub fn get_type(&self) -> String {
1525 match &self.discr_value {
1526 Some(discr) => format!("{} {}", discr, self.child.get_type()),
1527 None => self.child.get_type(),
1528 }
1529 }
1530}
1531
1532#[derive(Debug, Clone)]
1534pub struct VariantPartValue<R: Reader<Offset = usize>> {
1535 pub variant: Option<MemberValue<R>>,
1537
1538 pub variants: Vec<VariantValue<R>>,
1540 }
1545
1546impl<R: Reader<Offset = usize>> fmt::Display for VariantPartValue<R> {
1547 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1548 let mut variants = "{".to_string();
1549 for v in &self.variants {
1550 variants = format!("{} {},", variants, v);
1551 }
1552 variants = format!("{} {}", variants, "}");
1553 match &self.variant {
1554 Some(variant) => write!(f, "< variant: {} >, {}", variant, variants),
1556 None => write!(f, "{}", variants),
1557 }
1558 }
1559}
1560
1561impl<R: Reader<Offset = usize>> VariantPartValue<R> {
1562 pub fn get_type(&self) -> String {
1564 match &self.variant {
1566 Some(variant) => variant.to_string(),
1567 None => "".to_owned(),
1568 }
1569 }
1570}
1571
1572#[derive(Debug, Clone)]
1574pub struct SubrangeTypeValue {
1575 pub lower_bound: Option<u64>,
1577
1578 pub count: Option<u64>,
1580
1581 pub base_type_value: Option<(BaseTypeValue, ValueInformation)>,
1583 }
1588
1589impl fmt::Display for SubrangeTypeValue {
1590 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1591 match self.get_count() {
1592 Ok(Some(count)) => write!(f, "{}", count),
1593 _ => write!(f, ""),
1594 }
1595 }
1596}
1597
1598impl SubrangeTypeValue {
1599 pub fn get_type(&self) -> String {
1601 match &self.base_type_value {
1602 Some((val, _)) => val.get_type(),
1603 None => "u64".to_string(),
1604 }
1605 }
1606
1607 pub fn get_count(&self) -> Result<Option<u64>> {
1608 match self.count {
1609 Some(val) => Ok(Some(val)),
1610 None => match &self.base_type_value {
1611 Some((btv, _)) => Ok(Some(get_udata(btv.clone())?)),
1612 None => Ok(None),
1613 },
1614 }
1615 }
1616}
1617
1618#[derive(Debug, Clone)]
1620pub enum BaseTypeValue {
1621 Generic(u64),
1623
1624 Address32(u32),
1626
1627 Reg32(u32),
1629
1630 Bool(bool),
1632
1633 U8(u8),
1635
1636 U16(u16),
1638
1639 U32(u32),
1641
1642 U64(u64),
1644
1645 I8(i8),
1647
1648 I16(i16),
1650
1651 I32(i32),
1653
1654 I64(i64),
1656
1657 F32(f32),
1659
1660 F64(f64),
1662}
1663
1664impl fmt::Display for BaseTypeValue {
1665 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1666 match self {
1667 BaseTypeValue::Bool(val) => write!(f, "{}", val),
1668 BaseTypeValue::Generic(val) => write!(f, "{}", val),
1669 BaseTypeValue::I8(val) => write!(f, "{}", val),
1670 BaseTypeValue::U8(val) => write!(f, "{}", val),
1671 BaseTypeValue::I16(val) => write!(f, "{}", val),
1672 BaseTypeValue::U16(val) => write!(f, "{}", val),
1673 BaseTypeValue::I32(val) => write!(f, "{}", val),
1674 BaseTypeValue::U32(val) => write!(f, "{}", val),
1675 BaseTypeValue::I64(val) => write!(f, "{}", val),
1676 BaseTypeValue::U64(val) => write!(f, "{}", val),
1677 BaseTypeValue::F32(val) => write!(f, "{}", val),
1678 BaseTypeValue::F64(val) => write!(f, "{}", val),
1679 BaseTypeValue::Address32(val) => write!(f, "'Address' {:#10x}", val),
1680 BaseTypeValue::Reg32(val) => write!(f, "0x{:x}", val),
1681 }
1682 }
1683}
1684
1685impl BaseTypeValue {
1686 pub fn parse_base_type(data: Vec<u8>, encoding: DwAte) -> Result<BaseTypeValue> {
1696 if data.is_empty() {
1697 return Err(anyhow!("Expected data to be larger then 0"));
1698 }
1699
1700 Ok(match (encoding, data.len()) {
1702 (DwAte(1), 4) => BaseTypeValue::Address32(u32::from_le_bytes(match data.try_into() {
1704 Ok(val) => val,
1705 Err(err) => {
1706 error!("{:?}", err);
1707 return Err(anyhow!("{:?}", err));
1708 }
1709 })), (DwAte(2), 1) => BaseTypeValue::Bool(
1711 (u8::from_le_bytes(match data.try_into() {
1712 Ok(val) => val,
1713 Err(err) => {
1714 error!("{:?}", err);
1715 return Err(anyhow!("{:?}", err));
1716 }
1717 })) == 1,
1718 ), (DwAte(2), 2) => BaseTypeValue::Bool(
1720 (u16::from_le_bytes(match data.try_into() {
1721 Ok(val) => val,
1722 Err(err) => {
1723 error!("{:?}", err);
1724 return Err(anyhow!("{:?}", err));
1725 }
1726 })) == 1,
1727 ), (DwAte(2), 4) => BaseTypeValue::Bool(
1729 (u32::from_le_bytes(match data.try_into() {
1730 Ok(val) => val,
1731 Err(err) => {
1732 error!("{:?}", err);
1733 return Err(anyhow!("{:?}", err));
1734 }
1735 })) == 1,
1736 ), (DwAte(4), 4) => BaseTypeValue::F32(f32::from_le_bytes(match data.try_into() {
1740 Ok(val) => val,
1741 Err(err) => {
1742 error!("{:?}", err);
1743 return Err(anyhow!("{:?}", err));
1744 }
1745 })), (DwAte(4), 8) => BaseTypeValue::F64(f64::from_le_bytes(match data.try_into() {
1747 Ok(val) => val,
1748 Err(err) => {
1749 error!("{:?}", err);
1750 return Err(anyhow!("{:?}", err));
1751 }
1752 })), (DwAte(5), 1) => BaseTypeValue::I8(i8::from_le_bytes(match data.try_into() {
1755 Ok(val) => val,
1756 Err(err) => {
1757 error!("{:?}", err);
1758 return Err(anyhow!("{:?}", err));
1759 }
1760 })), (DwAte(5), 2) => BaseTypeValue::I16(i16::from_le_bytes(match data.try_into() {
1762 Ok(val) => val,
1763 Err(err) => {
1764 error!("{:?}", err);
1765 return Err(anyhow!("{:?}", err));
1766 }
1767 })), (DwAte(5), 4) => BaseTypeValue::I32(i32::from_le_bytes(match data.try_into() {
1769 Ok(val) => val,
1770 Err(err) => {
1771 error!("{:?}", err);
1772 return Err(anyhow!("{:?}", err));
1773 }
1774 })), (DwAte(5), 8) => BaseTypeValue::I64(i64::from_le_bytes(match data.try_into() {
1776 Ok(val) => val,
1777 Err(err) => {
1778 error!("{:?}", err);
1779 return Err(anyhow!("{:?}", err));
1780 }
1781 })), (DwAte(7), 1) => BaseTypeValue::U8(u8::from_le_bytes(match data.try_into() {
1785 Ok(val) => val,
1786 Err(err) => {
1787 error!("{:?}", err);
1788 return Err(anyhow!("{:?}", err));
1789 }
1790 })), (DwAte(7), 2) => BaseTypeValue::U16(u16::from_le_bytes(match data.try_into() {
1792 Ok(val) => val,
1793 Err(err) => {
1794 error!("{:?}", err);
1795 return Err(anyhow!("{:?}", err));
1796 }
1797 })), (DwAte(7), 4) => BaseTypeValue::U32(u32::from_le_bytes(match data.try_into() {
1799 Ok(val) => val,
1800 Err(err) => {
1801 error!("{:?}", err);
1802 return Err(anyhow!("{:?}", err));
1803 }
1804 })), (DwAte(7), 8) => BaseTypeValue::U64(u64::from_le_bytes(match data.try_into() {
1806 Ok(val) => val,
1807 Err(err) => {
1808 error!("{:?}", err);
1809 return Err(anyhow!("{:?}", err));
1810 }
1811 })), _ => {
1813 error!("encoding {}, byte_size: {}", encoding, data.len());
1814 return Err(anyhow!("encoding {}, byte_size: {}", encoding, data.len()));
1815 }
1816 })
1817 }
1818
1819 pub fn get_type(&self) -> String {
1821 match self {
1822 BaseTypeValue::Bool(_) => "bool".to_owned(),
1823 BaseTypeValue::Generic(_) => "<unknown>".to_owned(),
1824 BaseTypeValue::I8(_) => "i8".to_owned(),
1825 BaseTypeValue::U8(_) => "u8".to_owned(),
1826 BaseTypeValue::I16(_) => "i16".to_owned(),
1827 BaseTypeValue::U16(_) => "u16".to_owned(),
1828 BaseTypeValue::I32(_) => "i32".to_owned(),
1829 BaseTypeValue::U32(_) => "u32".to_owned(),
1830 BaseTypeValue::I64(_) => "i64".to_owned(),
1831 BaseTypeValue::U64(_) => "u64".to_owned(),
1832 BaseTypeValue::F32(_) => "f32".to_owned(),
1833 BaseTypeValue::F64(_) => "f63".to_owned(),
1834 BaseTypeValue::Address32(_) => "<32 bit address>".to_owned(),
1835 BaseTypeValue::Reg32(_) => "<32 bit register value>".to_owned(),
1836 }
1837 }
1838}
1839
1840pub fn convert_to_gimli_value(value: BaseTypeValue) -> gimli::Value {
1846 match value {
1847 BaseTypeValue::Bool(val) => gimli::Value::Generic(match val {
1848 true => 1,
1849 false => 0,
1850 }),
1851 BaseTypeValue::Generic(val) => gimli::Value::Generic(val),
1852 BaseTypeValue::I8(val) => gimli::Value::I8(val),
1853 BaseTypeValue::U8(val) => gimli::Value::U8(val),
1854 BaseTypeValue::I16(val) => gimli::Value::I16(val),
1855 BaseTypeValue::U16(val) => gimli::Value::U16(val),
1856 BaseTypeValue::I32(val) => gimli::Value::I32(val),
1857 BaseTypeValue::U32(val) => gimli::Value::U32(val),
1858 BaseTypeValue::I64(val) => gimli::Value::I64(val),
1859 BaseTypeValue::U64(val) => gimli::Value::U64(val),
1860 BaseTypeValue::F32(val) => gimli::Value::F32(val),
1861 BaseTypeValue::F64(val) => gimli::Value::F64(val),
1862 BaseTypeValue::Address32(val) => gimli::Value::Generic(val as u64),
1863 BaseTypeValue::Reg32(val) => gimli::Value::U32(val),
1864 }
1865}
1866
1867pub fn convert_from_gimli_value(value: gimli::Value) -> BaseTypeValue {
1873 match value {
1874 gimli::Value::Generic(val) => BaseTypeValue::Generic(val),
1875 gimli::Value::I8(val) => BaseTypeValue::I8(val),
1876 gimli::Value::U8(val) => BaseTypeValue::U8(val),
1877 gimli::Value::I16(val) => BaseTypeValue::I16(val),
1878 gimli::Value::U16(val) => BaseTypeValue::U16(val),
1879 gimli::Value::I32(val) => BaseTypeValue::I32(val),
1880 gimli::Value::U32(val) => BaseTypeValue::U32(val),
1881 gimli::Value::I64(val) => BaseTypeValue::I64(val),
1882 gimli::Value::U64(val) => BaseTypeValue::U64(val),
1883 gimli::Value::F32(val) => BaseTypeValue::F32(val),
1884 gimli::Value::F64(val) => BaseTypeValue::F64(val),
1885 }
1886}
1887
1888fn get_type_info<R: Reader<Offset = usize>>(
1896 dwarf: &gimli::Dwarf<R>,
1897 unit: &gimli::Unit<R>,
1898 die: &gimli::DebuggingInformationEntry<'_, '_, R>,
1899) -> Result<(gimli::Unit<R>, gimli::UnitOffset)> {
1900 let (unit_offset, die_offset) = match attributes::type_attribute(dwarf, unit, die)? {
1901 Some(val) => val,
1902 None => {
1903 error!("Die doesn't have the required DW_AT_type attribute");
1904 return Err(anyhow!(
1905 "Die doesn't have the required DW_AT_type attribute"
1906 ));
1907 }
1908 };
1909 let unit = match unit_offset {
1910 gimli::UnitSectionOffset::DebugInfoOffset(offset) => {
1911 let header = dwarf.debug_info.header_from_offset(offset)?;
1912 dwarf.unit(header)?
1913 }
1914 gimli::UnitSectionOffset::DebugTypesOffset(_offset) => {
1915 let mut iter = dwarf.debug_types.units();
1916 let mut result = None;
1917 while let Some(header) = iter.next()? {
1918 if header.offset() == unit_offset {
1919 result = Some(dwarf.unit(header)?);
1920 break;
1921 }
1922 }
1923 match result {
1924 Some(val) => val,
1925 None => {
1926 error!("Could not get unit from unit offset");
1927 return Err(anyhow!("Could not get unit from unit offset"));
1928 }
1929 }
1930 }
1931 };
1932
1933 Ok((unit, die_offset))
1934}
1935
1936fn check_alignment<R: Reader<Offset = usize>>(
1944 die: &gimli::DebuggingInformationEntry<'_, '_, R>,
1945 mut data_offset: u64,
1946 pieces: &Vec<MyPiece<R>>,
1947) -> Result<()> {
1948 match attributes::alignment_attribute(die)? {
1949 Some(alignment) => {
1950 if pieces.is_empty() {
1951 return Ok(());
1952 }
1953
1954 if pieces.is_empty() {
1955 data_offset = 0;
1956 }
1957
1958 if let Location::Address { address } = pieces[0].piece.location {
1959 let mut addr = address + (data_offset / 4) * 4;
1960 addr -= addr % 4; if addr % alignment != 0 {
1963 error!("Address not aligned");
1964 return Err(anyhow!("Address not aligned"));
1965 }
1966 };
1967 }
1968 None => (),
1969 };
1970
1971 Ok(())
1972}
1973
1974fn get_children<R: Reader<Offset = usize>>(
1981 unit: &gimli::Unit<R>,
1982 die: &gimli::DebuggingInformationEntry<'_, '_, R>,
1983) -> Result<Vec<gimli::UnitOffset>> {
1984 let mut result = Vec::new();
1985 let mut tree = unit.entries_tree(Some(die.offset()))?;
1986 let node = tree.root()?;
1987
1988 let mut children = node.children();
1989 while let Some(child) = children.next()? {
1990 result.push(child.entry().offset());
1991 }
1992
1993 Ok(result)
1994}
1995
1996fn trim_piece_bytes<R: Reader<Offset = usize>>(
2007 mut bytes: Vec<u8>,
2008 piece: &Piece<R>,
2009 byte_size: usize,
2010) -> Vec<u8> {
2011 let piece_byte_size = match piece.size_in_bits {
2012 Some(size) => ((size + 8 - 1) / 8) as usize,
2013 None => byte_size,
2014 };
2015
2016 let piece_byte_offset = match piece.bit_offset {
2017 Some(offset) => {
2018 ((offset + 8 - 1) / 8) as usize
2023 }
2024 None => 0,
2025 };
2026
2027 for _ in 0..piece_byte_offset {
2028 bytes.pop();
2029 }
2030
2031 while bytes.len() > piece_byte_size {
2032 bytes.remove(0);
2034 }
2035
2036 bytes
2037}
2038
2039#[derive(Debug, Clone)]
2041pub struct ValueInformation {
2042 pub raw: Option<Vec<u8>>, pub pieces: Vec<ValuePiece>,
2044}
2045
2046impl ValueInformation {
2047 pub fn new(raw: Option<Vec<u8>>, pieces: Vec<ValuePiece>) -> ValueInformation {
2054 ValueInformation { raw, pieces }
2055 }
2056}
2057
2058#[derive(Debug, Clone)]
2060pub enum ValuePiece {
2061 Register {
2063 register: u16,
2065
2066 byte_size: usize,
2068 },
2069
2070 Memory {
2072 address: u32,
2074
2075 byte_size: usize,
2077 },
2078
2079 Dwarf {
2081 value: Option<gimli::Value>,
2084 },
2085
2086 Bytes { bytes: Vec<u8> },
2088}