From 0feeab81a5294e73fe1991f1810cff3f72fbd3a6 Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Fri, 26 Apr 2024 15:06:07 +1000 Subject: [PATCH] read/macho: fix data for segments in dyld caches This is for operations on the segment itself, and for section relocations. Individual section data was already using the correct source. --- src/read/macho/file.rs | 19 ++++--------------- src/read/macho/section.rs | 24 +++++++++--------------- src/read/macho/segment.rs | 2 +- 3 files changed, 14 insertions(+), 31 deletions(-) diff --git a/src/read/macho/file.rs b/src/read/macho/file.rs index c845c559..54170087 100644 --- a/src/read/macho/file.rs +++ b/src/read/macho/file.rs @@ -44,7 +44,7 @@ where pub(super) header_offset: u64, pub(super) header: &'data Mach, pub(super) segments: Vec>, - pub(super) sections: Vec>, + pub(super) sections: Vec>, pub(super) symbols: SymbolTable<'data, Mach, R>, } @@ -65,11 +65,10 @@ where if let Ok(mut commands) = header.load_commands(endian, data, 0) { while let Ok(Some(command)) = commands.next() { if let Some((segment, section_data)) = Mach::Segment::from_command(command)? { - let segment_index = segments.len(); segments.push(MachOSegmentInternal { segment, data }); for section in segment.sections(endian, section_data)? { let index = SectionIndex(sections.len() + 1); - sections.push(MachOSectionInternal::parse(index, segment_index, section)); + sections.push(MachOSectionInternal::parse(index, section, data)); } } else if let Some(symtab) = command.symtab()? { symbols = symtab.symbols(endian, data)?; @@ -118,12 +117,11 @@ where if segment.name() == macho::SEG_LINKEDIT.as_bytes() { linkedit_data = Some(data); } - let segment_index = segments.len(); segments.push(MachOSegmentInternal { segment, data }); for section in segment.sections(endian, section_data)? { let index = SectionIndex(sections.len() + 1); - sections.push(MachOSectionInternal::parse(index, segment_index, section)); + sections.push(MachOSectionInternal::parse(index, section, data)); } } else if let Some(st) = command.symtab()? { symtab = Some(st); @@ -154,7 +152,7 @@ where pub(super) fn section_internal( &self, index: SectionIndex, - ) -> Result<&MachOSectionInternal<'data, Mach>> { + ) -> Result<&MachOSectionInternal<'data, Mach, R>> { index .0 .checked_sub(1) @@ -162,15 +160,6 @@ where .read_error("Invalid Mach-O section index") } - pub(super) fn segment_internal( - &self, - index: usize, - ) -> Result<&MachOSegmentInternal<'data, Mach, R>> { - self.segments - .get(index) - .read_error("Invalid Mach-O segment index") - } - /// Returns the endianness. pub fn endian(&self) -> Mach::Endian { self.endian diff --git a/src/read/macho/section.rs b/src/read/macho/section.rs index 16c199c3..4aa26539 100644 --- a/src/read/macho/section.rs +++ b/src/read/macho/section.rs @@ -25,7 +25,7 @@ where R: ReadRef<'data>, { pub(super) file: &'file MachOFile<'data, Mach, R>, - pub(super) iter: slice::Iter<'file, MachOSectionInternal<'data, Mach>>, + pub(super) iter: slice::Iter<'file, MachOSectionInternal<'data, Mach, R>>, } impl<'data, 'file, Mach, R> fmt::Debug for MachOSectionIterator<'data, 'file, Mach, R> @@ -71,7 +71,7 @@ where R: ReadRef<'data>, { pub(super) file: &'file MachOFile<'data, Mach, R>, - pub(super) internal: MachOSectionInternal<'data, Mach>, + pub(super) internal: MachOSectionInternal<'data, Mach, R>, } impl<'data, 'file, Mach, R> MachOSection<'data, 'file, Mach, R> @@ -80,11 +80,9 @@ where R: ReadRef<'data>, { fn bytes(&self) -> Result<&'data [u8]> { - let segment_index = self.internal.segment_index; - let segment = self.file.segment_internal(segment_index)?; self.internal .section - .data(self.file.endian, segment.data) + .data(self.file.endian, self.internal.data) .read_error("Invalid Mach-O section size or offset") } } @@ -193,7 +191,7 @@ where relocations: self .internal .section - .relocations(self.file.endian, self.file.data) + .relocations(self.file.endian, self.internal.data) .unwrap_or(&[]) .iter(), } @@ -211,19 +209,15 @@ where } #[derive(Debug, Clone, Copy)] -pub(super) struct MachOSectionInternal<'data, Mach: MachHeader> { +pub(super) struct MachOSectionInternal<'data, Mach: MachHeader, R: ReadRef<'data>> { pub index: SectionIndex, - pub segment_index: usize, pub kind: SectionKind, pub section: &'data Mach::Section, + pub data: R, } -impl<'data, Mach: MachHeader> MachOSectionInternal<'data, Mach> { - pub(super) fn parse( - index: SectionIndex, - segment_index: usize, - section: &'data Mach::Section, - ) -> Self { +impl<'data, Mach: MachHeader, R: ReadRef<'data>> MachOSectionInternal<'data, Mach, R> { + pub(super) fn parse(index: SectionIndex, section: &'data Mach::Section, data: R) -> Self { // TODO: we don't validate flags, should we? let kind = match (section.segment_name(), section.name()) { (b"__TEXT", b"__text") => SectionKind::Text, @@ -246,9 +240,9 @@ impl<'data, Mach: MachHeader> MachOSectionInternal<'data, Mach> { }; MachOSectionInternal { index, - segment_index, kind, section, + data, } } } diff --git a/src/read/macho/segment.rs b/src/read/macho/segment.rs index c889ad24..2373cbe8 100644 --- a/src/read/macho/segment.rs +++ b/src/read/macho/segment.rs @@ -69,7 +69,7 @@ where fn bytes(&self) -> Result<&'data [u8]> { self.internal .segment - .data(self.file.endian, self.file.data) + .data(self.file.endian, self.internal.data) .read_error("Invalid Mach-O segment size or offset") } }