1 use crate::common::{DebugAddrBase, DebugAddrIndex, SectionId}; 2 use crate::read::{Reader, ReaderOffset, Result, Section}; 3 4 /// The raw contents of the `.debug_addr` section. 5 #[derive(Debug, Default, Clone, Copy)] 6 pub struct DebugAddr<R> { 7 section: R, 8 } 9 10 impl<R: Reader> DebugAddr<R> { 11 // TODO: add an iterator over the sets of addresses in the section. 12 // This is not needed for common usage of the section though. 13 14 /// Returns the address at the given `base` and `index`. 15 /// 16 /// A set of addresses in the `.debug_addr` section consists of a header 17 /// followed by a series of addresses. 18 /// 19 /// The `base` must be the `DW_AT_addr_base` value from the compilation unit DIE. 20 /// This is an offset that points to the first address following the header. 21 /// 22 /// The `index` is the value of a `DW_FORM_addrx` attribute. 23 /// 24 /// The `address_size` must be the size of the address for the compilation unit. 25 /// This value must also match the header. However, note that we do not parse the 26 /// header to validate this, since locating the header is unreliable, and the GNU 27 /// extensions do not emit it. get_address( &self, address_size: u8, base: DebugAddrBase<R::Offset>, index: DebugAddrIndex<R::Offset>, ) -> Result<u64>28 pub fn get_address( 29 &self, 30 address_size: u8, 31 base: DebugAddrBase<R::Offset>, 32 index: DebugAddrIndex<R::Offset>, 33 ) -> Result<u64> { 34 let input = &mut self.section.clone(); 35 input.skip(base.0)?; 36 input.skip(R::Offset::from_u64( 37 index.0.into_u64() * u64::from(address_size), 38 )?)?; 39 input.read_address(address_size) 40 } 41 } 42 43 impl<T> DebugAddr<T> { 44 /// Create a `DebugAddr` section that references the data in `self`. 45 /// 46 /// This is useful when `R` implements `Reader` but `T` does not. 47 /// 48 /// ## Example Usage 49 /// 50 /// ```rust,no_run 51 /// # let load_section = || unimplemented!(); 52 /// // Read the DWARF section into a `Vec` with whatever object loader you're using. 53 /// let owned_section: gimli::DebugAddr<Vec<u8>> = load_section(); 54 /// // Create a reference to the DWARF section. 55 /// let section = owned_section.borrow(|section| { 56 /// gimli::EndianSlice::new(§ion, gimli::LittleEndian) 57 /// }); 58 /// ``` borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAddr<R> where F: FnMut(&'a T) -> R,59 pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAddr<R> 60 where 61 F: FnMut(&'a T) -> R, 62 { 63 borrow(&self.section).into() 64 } 65 } 66 67 impl<R> Section<R> for DebugAddr<R> { id() -> SectionId68 fn id() -> SectionId { 69 SectionId::DebugAddr 70 } 71 reader(&self) -> &R72 fn reader(&self) -> &R { 73 &self.section 74 } 75 } 76 77 impl<R> From<R> for DebugAddr<R> { from(section: R) -> Self78 fn from(section: R) -> Self { 79 DebugAddr { section } 80 } 81 } 82 83 #[cfg(test)] 84 mod tests { 85 use super::*; 86 use crate::read::EndianSlice; 87 use crate::test_util::GimliSectionMethods; 88 use crate::{Format, LittleEndian}; 89 use test_assembler::{Endian, Label, LabelMaker, Section}; 90 91 #[test] test_get_address()92 fn test_get_address() { 93 for format in vec![Format::Dwarf32, Format::Dwarf64] { 94 for address_size in vec![4, 8] { 95 let zero = Label::new(); 96 let length = Label::new(); 97 let start = Label::new(); 98 let first = Label::new(); 99 let end = Label::new(); 100 let mut section = Section::with_endian(Endian::Little) 101 .mark(&zero) 102 .initial_length(format, &length, &start) 103 .D16(5) 104 .D8(address_size) 105 .D8(0) 106 .mark(&first); 107 for i in 0..20 { 108 section = section.word(address_size, 1000 + i); 109 } 110 section = section.mark(&end); 111 length.set_const((&end - &start) as u64); 112 113 let section = section.get_contents().unwrap(); 114 let debug_addr = DebugAddr::from(EndianSlice::new(§ion, LittleEndian)); 115 let base = DebugAddrBase((&first - &zero) as usize); 116 117 assert_eq!( 118 debug_addr.get_address(address_size, base, DebugAddrIndex(0)), 119 Ok(1000) 120 ); 121 assert_eq!( 122 debug_addr.get_address(address_size, base, DebugAddrIndex(19)), 123 Ok(1019) 124 ); 125 } 126 } 127 } 128 } 129