diff --git a/crates/examples/src/bin/dwarfdump.rs b/crates/examples/src/bin/dwarfdump.rs index f1dd856e..ffad99ba 100644 --- a/crates/examples/src/bin/dwarfdump.rs +++ b/crates/examples/src/bin/dwarfdump.rs @@ -2162,25 +2162,16 @@ fn dump_aranges( while let Some(header) = headers.next()? { writeln!( w, - "Address Range Header: length = 0x{:08x}, version = 0x{:04x}, cu_offset = 0x{:08x}, addr_size = 0x{:02x}, seg_size = 0x{:02x}", + "Address Range Header: length = 0x{:08x}, version = 0x{:04x}, cu_offset = 0x{:08x}, addr_size = 0x{:02x}", header.length(), header.encoding().version, header.debug_info_offset().0, header.encoding().address_size, - header.segment_size(), )?; let mut aranges = header.entries(); while let Some(arange) = aranges.next()? { let range = arange.range(); - if let Some(segment) = arange.segment() { - writeln!( - w, - "[0x{:016x}, 0x{:016x}) segment 0x{:x}", - range.begin, range.end, segment - )?; - } else { - writeln!(w, "[0x{:016x}, 0x{:016x})", range.begin, range.end)?; - } + writeln!(w, "[0x{:016x}, 0x{:016x})", range.begin, range.end)?; } } Ok(()) diff --git a/src/common.rs b/src/common.rs index cad9568a..515718f3 100644 --- a/src/common.rs +++ b/src/common.rs @@ -48,8 +48,6 @@ pub struct Encoding { /// The size of an address. pub address_size: u8, - // The size of a segment selector. - // TODO: pub segment_size: u8, /// Whether the DWARF format is 32- or 64-bit. pub format: Format, diff --git a/src/read/aranges.rs b/src/read/aranges.rs index 12bcec7e..ddfe135f 100644 --- a/src/read/aranges.rs +++ b/src/read/aranges.rs @@ -135,7 +135,6 @@ where encoding: Encoding, length: Offset, debug_info_offset: DebugInfoOffset, - segment_size: u8, entries: R, } @@ -160,16 +159,17 @@ where let debug_info_offset = rest.read_offset(format).map(DebugInfoOffset)?; let address_size = rest.read_u8()?; let segment_size = rest.read_u8()?; + if segment_size != 0 { + return Err(Error::UnsupportedSegmentSize); + } // unit_length + version + offset + address_size + segment_size let header_length = format.initial_length_size() + 2 + format.word_size() + 1 + 1; // The first tuple following the header in each set begins at an offset that is - // a multiple of the size of a single tuple (that is, the size of a segment selector - // plus twice the size of an address). + // a multiple of the size of a single tuple (that is, twice the size of an address). let tuple_length = address_size .checked_mul(2) - .and_then(|x| x.checked_add(segment_size)) .ok_or(Error::InvalidAddressRange)?; if tuple_length == 0 { return Err(Error::InvalidAddressRange); @@ -185,14 +185,12 @@ where format, version, address_size, - // TODO: segment_size }; Ok(ArangeHeader { offset, encoding, length, debug_info_offset, - segment_size, entries: rest, }) } @@ -215,12 +213,6 @@ where self.encoding } - /// Return the segment size for this set of entries. - #[inline] - pub fn segment_size(&self) -> u8 { - self.segment_size - } - /// Return the offset into the .debug_info section for this set of arange entries. #[inline] pub fn debug_info_offset(&self) -> DebugInfoOffset { @@ -233,7 +225,6 @@ where ArangeEntryIter { input: self.entries.clone(), encoding: self.encoding, - segment_size: self.segment_size, } } } @@ -246,7 +237,6 @@ where pub struct ArangeEntryIter { input: R, encoding: Encoding, - segment_size: u8, } impl ArangeEntryIter { @@ -261,7 +251,7 @@ impl ArangeEntryIter { return Ok(None); } - match ArangeEntry::parse(&mut self.input, self.encoding, self.segment_size) { + match ArangeEntry::parse(&mut self.input, self.encoding) { Ok(Some(entry)) => Ok(Some(entry)), Ok(None) => { self.input.empty(); @@ -288,57 +278,33 @@ impl fallible_iterator::FallibleIterator for ArangeEntryIter { /// A single parsed arange. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct ArangeEntry { - segment: Option, address: u64, length: u64, } impl ArangeEntry { /// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange. - fn parse( - input: &mut R, - encoding: Encoding, - segment_size: u8, - ) -> Result> { + fn parse(input: &mut R, encoding: Encoding) -> Result> { let address_size = encoding.address_size; - let tuple_length = R::Offset::from_u8(2 * address_size + segment_size); + let tuple_length = R::Offset::from_u8(2 * address_size); if tuple_length > input.len() { input.empty(); return Ok(None); } - let segment = if segment_size != 0 { - input.read_address(segment_size)? - } else { - 0 - }; let address = input.read_address(address_size)?; let length = input.read_address(address_size)?; - match (segment, address, length) { + match (address, length) { // This is meant to be a null terminator, but in practice it can occur // before the end, possibly due to a linker omitting a function and // leaving an unrelocated entry. - (0, 0, 0) => Self::parse(input, encoding, segment_size), - _ => Ok(Some(ArangeEntry { - segment: if segment_size != 0 { - Some(segment) - } else { - None - }, - address, - length, - })), + (0, 0) => Self::parse(input, encoding), + _ => Ok(Some(ArangeEntry { address, length })), } } - /// Return the segment selector of this arange. - #[inline] - pub fn segment(&self) -> Option { - self.segment - } - /// Return the beginning address of this arange. #[inline] pub fn address(&self) -> u64 { @@ -426,8 +392,8 @@ mod tests { fn test_parse_header_ok() { #[rustfmt::skip] let buf = [ - // 32-bit length = 32. - 0x20, 0x00, 0x00, 0x00, + // 32-bit length = 28 (8 bytes header, 4 bytes padding, 16 bytes tuple data). + 0x1c, 0x00, 0x00, 0x00, // Version. 0x02, 0x00, // Offset. @@ -435,11 +401,10 @@ mod tests { // Address size. 0x08, // Segment size. - 0x04, - // Length to here = 12, tuple length = 20. + 0x00, + // Length to here = 12, tuple length = 16. // Padding to tuple length multiple = 4. 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, // Dummy arange tuple data. 0x20, 0x00, 0x00, 0x00, @@ -472,9 +437,8 @@ mod tests { version: 2, address_size: 8, }, - length: 0x20, + length: 0x1c, debug_info_offset: DebugInfoOffset(0x0403_0201), - segment_size: 4, entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian), } ); @@ -493,7 +457,7 @@ mod tests { // Address size. 0xff, // Segment size. - 0xff, + 0x00, // Length to here = 12, tuple length = 20. // Padding to tuple length multiple = 4. 0x10, 0x00, 0x00, 0x00, @@ -566,49 +530,13 @@ mod tests { version: 2, address_size: 4, }; - let segment_size = 0; let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]; let rest = &mut EndianSlice::new(&buf, LittleEndian); - let entry = - ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok"); - assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)); - assert_eq!( - entry, - Some(ArangeEntry { - segment: None, - address: 0x0403_0201, - length: 0x0807_0605, - }) - ); - } - - #[test] - fn test_parse_entry_segment() { - let encoding = Encoding { - format: Format::Dwarf32, - version: 2, - address_size: 4, - }; - let segment_size = 8; - #[rustfmt::skip] - let buf = [ - // Segment. - 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, - // Address. - 0x01, 0x02, 0x03, 0x04, - // Length. - 0x05, 0x06, 0x07, 0x08, - // Next tuple. - 0x09 - ]; - let rest = &mut EndianSlice::new(&buf, LittleEndian); - let entry = - ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok"); + let entry = ArangeEntry::parse(rest, encoding).expect("should parse entry ok"); assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)); assert_eq!( entry, Some(ArangeEntry { - segment: Some(0x1817_1615_1413_1211), address: 0x0403_0201, length: 0x0807_0605, }) @@ -622,7 +550,6 @@ mod tests { version: 2, address_size: 4, }; - let segment_size = 0; #[rustfmt::skip] let buf = [ // Zero tuple. @@ -635,13 +562,11 @@ mod tests { 0x09 ]; let rest = &mut EndianSlice::new(&buf, LittleEndian); - let entry = - ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok"); + let entry = ArangeEntry::parse(rest, encoding).expect("should parse entry ok"); assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)); assert_eq!( entry, Some(ArangeEntry { - segment: None, address: 0x0403_0201, length: 0x0807_0605, }) diff --git a/src/read/cfi.rs b/src/read/cfi.rs index 5aa88468..93386012 100644 --- a/src/read/cfi.rs +++ b/src/read/cfi.rs @@ -35,7 +35,6 @@ use crate::read::{ pub struct DebugFrame { section: R, address_size: u8, - segment_size: u8, vendor: Vendor, } @@ -48,14 +47,6 @@ impl DebugFrame { self.address_size = address_size } - /// Set the size of a segment selector in bytes. - /// - /// This defaults to 0. - /// This is only used if the CIE version is less than 4. - pub fn set_segment_size(&mut self, segment_size: u8) { - self.segment_size = segment_size - } - /// Set the vendor extensions to use. /// /// This defaults to `Vendor::Default`. @@ -100,11 +91,10 @@ impl Section for DebugFrame { impl From for DebugFrame { fn from(section: R) -> Self { - // Default to no segments and native word size. + // Default to native word size. DebugFrame { section, address_size: mem::size_of::() as u8, - segment_size: 0, vendor: Vendor::Default, } } @@ -631,9 +621,6 @@ pub trait _UnwindSectionPrivate { /// The address size to use if `has_address_and_segment_sizes` returns false. fn address_size(&self) -> u8; - /// The segment size to use if `has_address_and_segment_sizes` returns false. - fn segment_size(&self) -> u8; - /// The vendor extensions to use. fn vendor(&self) -> Vendor; } @@ -828,10 +815,6 @@ impl _UnwindSectionPrivate for DebugFrame { self.address_size } - fn segment_size(&self) -> u8 { - self.segment_size - } - fn vendor(&self) -> Vendor { self.vendor } @@ -872,10 +855,6 @@ impl _UnwindSectionPrivate for EhFrame { self.address_size } - fn segment_size(&self) -> u8 { - 0 - } - fn vendor(&self) -> Vendor { self.vendor } @@ -1297,10 +1276,6 @@ where /// > must match the address size here. address_size: u8, - /// "The size of a segment selector in this CIE and any FDEs that use it, in - /// bytes." - segment_size: u8, - /// "A constant that is factored out of all advance location instructions /// (see Section 6.4.2.1)." code_alignment_factor: u64, @@ -1360,12 +1335,15 @@ impl CommonInformationEntry { let mut augmentation_string = rest.read_null_terminated_slice()?; - let (address_size, segment_size) = if Section::has_address_and_segment_sizes(version) { + let address_size = if Section::has_address_and_segment_sizes(version) { let address_size = rest.read_u8()?; let segment_size = rest.read_u8()?; - (address_size, segment_size) + if segment_size != 0 { + return Err(Error::UnsupportedSegmentSize); + } + address_size } else { - (section.address_size(), section.segment_size()) + section.address_size() }; let code_alignment_factor = rest.read_uleb128()?; @@ -1396,7 +1374,6 @@ impl CommonInformationEntry { version, augmentation, address_size, - segment_size, code_alignment_factor, data_alignment_factor, return_address_register, @@ -1635,7 +1612,6 @@ where /// > The address of the first location associated with this table entry. If /// > the segment_size field of this FDE's CIE is non-zero, the initial /// > location is preceded by a segment selector of the given length. - initial_segment: u64, initial_address: u64, /// "The number of bytes of program instructions described by this entry." @@ -1668,12 +1644,6 @@ impl FrameDescriptionEntry { { let cie = get_cie(section, bases, cie_pointer)?; - let initial_segment = if cie.segment_size > 0 { - rest.read_address(cie.segment_size)? - } else { - 0 - }; - let mut parameters = PointerEncodingParameters { bases: &bases.eh_frame, func_base: None, @@ -1699,7 +1669,6 @@ impl FrameDescriptionEntry { length, format, cie, - initial_segment, initial_address, address_range, augmentation: aug_data, @@ -3766,7 +3735,7 @@ mod tests { let section = section.D8(0); let section = if T::has_address_and_segment_sizes(cie.version) { - section.D8(cie.address_size).D8(cie.segment_size) + section.D8(cie.address_size).D8(0) } else { section }; @@ -3817,13 +3786,6 @@ mod tests { } }; - let section = match fde.cie.segment_size { - 0 => section, - 4 => section.D32(fde.initial_segment as u32), - 8 => section.D64(fde.initial_segment), - x => panic!("Unsupported test segment size: {}", x), - }; - let section = match fde.cie.address_size { 4 => section .D32(fde.initial_address() as u32) @@ -3977,7 +3939,6 @@ mod tests { version: 99, augmentation: None, address_size: 4, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 2, return_address_register: Register(3), @@ -4038,7 +3999,6 @@ mod tests { version, augmentation: None, address_size, - segment_size: 0, code_alignment_factor: 16, data_alignment_factor: 32, return_address_register: Register(1), @@ -4085,7 +4045,6 @@ mod tests { version: 4, augmentation: None, address_size: 4, - segment_size: 0, code_alignment_factor: 0, data_alignment_factor: 0, return_address_register: Register(3), @@ -4174,7 +4133,6 @@ mod tests { augmentation: None, // DWARF32 with a 64 bit address size! Holy moly! address_size: 8, - segment_size: 0, code_alignment_factor: 3, data_alignment_factor: 2, return_address_register: Register(1), @@ -4186,7 +4144,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_beef, address_range: 39, augmentation: None, @@ -4211,56 +4168,6 @@ mod tests { assert_eq!(*rest, EndianSlice::new(&expected_rest, LittleEndian)); } - #[test] - fn test_parse_fde_32_with_segment_ok() { - let expected_rest = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - let cie_offset = 0xbad0_bad1; - let expected_instrs: Vec<_> = (0..92).map(|_| constants::DW_CFA_nop.0).collect(); - - let cie = CommonInformationEntry { - offset: 0, - length: 100, - format: Format::Dwarf32, - version: 4, - augmentation: None, - address_size: 4, - segment_size: 4, - code_alignment_factor: 3, - data_alignment_factor: 2, - return_address_register: Register(1), - initial_instructions: EndianSlice::new(&[], LittleEndian), - }; - - let mut fde = FrameDescriptionEntry { - offset: 0, - length: 0, - format: Format::Dwarf32, - cie: cie.clone(), - initial_segment: 0xbadb_ad11, - initial_address: 0xfeed_beef, - address_range: 999, - augmentation: None, - instructions: EndianSlice::new(&expected_instrs, LittleEndian), - }; - - let kind = debug_frame_le(); - let section = Section::with_endian(kind.endian()) - .fde(kind, cie_offset, &mut fde) - .append_bytes(&expected_rest); - - let section = section.get_contents().unwrap(); - let debug_frame = kind.section(§ion); - let rest = &mut EndianSlice::new(§ion, LittleEndian); - - let get_cie = |_: &_, _: &_, offset| { - assert_eq!(offset, DebugFrameOffset(cie_offset as usize)); - Ok(cie.clone()) - }; - - assert_eq!(parse_fde(debug_frame, rest, get_cie), Ok(fde)); - assert_eq!(*rest, EndianSlice::new(&expected_rest, LittleEndian)); - } - #[test] fn test_parse_fde_64_ok() { let expected_rest = [1, 2, 3, 4, 5, 6, 7, 8, 9]; @@ -4274,7 +4181,6 @@ mod tests { version: 4, augmentation: None, address_size: 8, - segment_size: 0, code_alignment_factor: 3, data_alignment_factor: 2, return_address_register: Register(1), @@ -4286,7 +4192,6 @@ mod tests { length: 0, format: Format::Dwarf64, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_beef, address_range: 999, augmentation: None, @@ -4323,7 +4228,6 @@ mod tests { version: 4, augmentation: None, address_size: 4, - segment_size: 0, code_alignment_factor: 16, data_alignment_factor: 32, return_address_register: Register(1), @@ -4359,7 +4263,6 @@ mod tests { version: 4, augmentation: None, address_size: 4, - segment_size: 0, code_alignment_factor: 16, data_alignment_factor: 32, return_address_register: Register(1), @@ -4371,7 +4274,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_beef, address_range: 39, augmentation: None, @@ -4424,7 +4326,6 @@ mod tests { version: 4, augmentation: None, address_size: 4, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 2, return_address_register: Register(3), @@ -4438,7 +4339,6 @@ mod tests { version: 4, augmentation: None, address_size: 4, - segment_size: 0, code_alignment_factor: 3, data_alignment_factor: 2, return_address_register: Register(1), @@ -4463,7 +4363,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie1.clone(), - initial_segment: 0, initial_address: 0xfeed_beef, address_range: 39, augmentation: None, @@ -4475,7 +4374,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie2.clone(), - initial_segment: 0, initial_address: 0xfeed_face, address_range: 9000, augmentation: None, @@ -4546,7 +4444,6 @@ mod tests { version: 4, augmentation: None, address_size: 4, - segment_size: 0, code_alignment_factor: 4, data_alignment_factor: 8, return_address_register: Register(12), @@ -5328,7 +5225,6 @@ mod tests { address_size: mem::size_of::() as u8, initial_instructions: EndianSlice::new(&[], LittleEndian), augmentation: None, - segment_size: 0, data_alignment_factor: 2, code_alignment_factor: 3, } @@ -5679,7 +5575,6 @@ mod tests { address_range: 0, augmentation: None, initial_address: 0, - initial_segment: 0, cie: cie.clone(), instructions: EndianSlice::new(&[], LittleEndian), }; @@ -5830,7 +5725,6 @@ mod tests { version: 4, augmentation: None, address_size: 8, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 1, return_address_register: Register(3), @@ -5847,7 +5741,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0, address_range: 100, augmentation: None, @@ -5905,7 +5798,6 @@ mod tests { version: 4, augmentation: None, address_size: 8, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 1, return_address_register: Register(3), @@ -5922,7 +5814,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0, address_range: 100, augmentation: None, @@ -5979,7 +5870,6 @@ mod tests { version: 4, augmentation: None, address_size: 8, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 1, return_address_register: Register(3), @@ -6000,7 +5890,6 @@ mod tests { version: 4, augmentation: None, address_size: 8, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 1, return_address_register: Register(3), @@ -6012,7 +5901,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie1.clone(), - initial_segment: 0, initial_address: 0, address_range: 100, augmentation: None, @@ -6024,7 +5912,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie2.clone(), - initial_segment: 0, initial_address: 0, address_range: 100, augmentation: None, @@ -6076,7 +5963,6 @@ mod tests { version: 4, augmentation: None, address_size: 8, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 1, return_address_register: Register(3), @@ -6113,7 +5999,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0, address_range: 100, augmentation: None, @@ -6253,7 +6138,6 @@ mod tests { version: 4, augmentation: None, address_size: 8, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 1, return_address_register: Register(3), @@ -6267,7 +6151,6 @@ mod tests { version: 4, augmentation: None, address_size: 4, - segment_size: 0, code_alignment_factor: 1, data_alignment_factor: 1, return_address_register: Register(1), @@ -6292,7 +6175,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie1.clone(), - initial_segment: 0, initial_address: 0xfeed_beef, address_range: 200, augmentation: None, @@ -6304,7 +6186,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie2.clone(), - initial_segment: 0, initial_address: 0xfeed_face, address_range: 9000, augmentation: None, @@ -6550,7 +6431,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 9, address_range: 4, augmentation: None, @@ -6561,7 +6441,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 20, address_range: 8, augmentation: None, @@ -6692,7 +6571,6 @@ mod tests { length: 0, format: Format::Dwarf64, cie: make_test_cie(), - initial_segment: 0, initial_address: 0xfeed_beef, address_range: 39, augmentation: None, @@ -6769,7 +6647,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_beef, address_range: 999, augmentation: None, @@ -6814,7 +6691,6 @@ mod tests { length: 0, format: Format::Dwarf64, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_beef, address_range: 999, augmentation: None, @@ -7057,7 +6933,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_face, address_range: 9000, augmentation: None, @@ -7095,7 +6970,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_face, address_range: 9000, augmentation: Some(AugmentationData::default()), @@ -7134,7 +7008,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_face, address_range: 9000, augmentation: Some(AugmentationData { @@ -7176,7 +7049,6 @@ mod tests { length: 0, format: Format::Dwarf32, cie: cie.clone(), - initial_segment: 0, initial_address: 0xfeed_face, address_range: 9000, augmentation: Some(AugmentationData { diff --git a/src/write/cfi.rs b/src/write/cfi.rs index d1339615..8d0a5205 100644 --- a/src/write/cfi.rs +++ b/src/write/cfi.rs @@ -212,8 +212,7 @@ impl CommonInformationEntry { if encoding.version >= 4 { w.write_u8(encoding.address_size)?; - // TODO: segment_selector_size - w.write_u8(0)?; + w.write_u8(0)?; // segment_selector_size } w.write_uleb128(self.code_alignment_factor.into())?;