Skip to content

Commit

Permalink
read/macho: fix data for segments in dyld caches
Browse files Browse the repository at this point in the history
This is for operations on the segment itself, and for section relocations.
Individual section data was already using the correct source.
  • Loading branch information
philipc committed Apr 26, 2024
1 parent 9650d64 commit 0feeab8
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 31 deletions.
19 changes: 4 additions & 15 deletions src/read/macho/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ where
pub(super) header_offset: u64,
pub(super) header: &'data Mach,
pub(super) segments: Vec<MachOSegmentInternal<'data, Mach, R>>,
pub(super) sections: Vec<MachOSectionInternal<'data, Mach>>,
pub(super) sections: Vec<MachOSectionInternal<'data, Mach, R>>,
pub(super) symbols: SymbolTable<'data, Mach, R>,
}

Expand All @@ -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)?;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -154,23 +152,14 @@ where
pub(super) fn section_internal(
&self,
index: SectionIndex,
) -> Result<&MachOSectionInternal<'data, Mach>> {
) -> Result<&MachOSectionInternal<'data, Mach, R>> {
index
.0
.checked_sub(1)
.and_then(|index| self.sections.get(index))
.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
Expand Down
24 changes: 9 additions & 15 deletions src/read/macho/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand All @@ -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")
}
}
Expand Down Expand Up @@ -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(),
}
Expand All @@ -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,
Expand All @@ -246,9 +240,9 @@ impl<'data, Mach: MachHeader> MachOSectionInternal<'data, Mach> {
};
MachOSectionInternal {
index,
segment_index,
kind,
section,
data,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/read/macho/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}
Expand Down

0 comments on commit 0feeab8

Please sign in to comment.