/// An iterator for the sections in a [`MachOFile32`](super::MachOFile32). pubtype MachOSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
MachOSectionIterator<'data, 'file, macho::MachHeader32<Endian>, R>; /// An iterator for the sections in a [`MachOFile64`](super::MachOFile64). pubtype MachOSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
MachOSectionIterator<'data, 'file, macho::MachHeader64<Endian>, R>;
/// An iterator for the sections in a [`MachOFile`]. pubstruct MachOSectionIterator<'data, 'file, Mach, R = &'data [u8]> where
Mach: MachHeader,
R: ReadRef<'data>,
{ pub(super) file: &'file MachOFile<'data, Mach, R>, pub(super) iter: slice::Iter<'file, MachOSectionInternal<'data, Mach, R>>,
}
impl<'data, 'file, Mach, R> fmt::Debug for MachOSectionIterator<'data, 'file, Mach, R> where
Mach: MachHeader,
R: ReadRef<'data>,
{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // It's painful to do much better than this
f.debug_struct("MachOSectionIterator").finish()
}
}
impl<'data, 'file, Mach, R> Iterator for MachOSectionIterator<'data, 'file, Mach, R> where
Mach: MachHeader,
R: ReadRef<'data>,
{ type Item = MachOSection<'data, 'file, Mach, R>;
/// A section in a [`MachOFile32`](super::MachOFile32). pubtype MachOSection32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
MachOSection<'data, 'file, macho::MachHeader32<Endian>, R>; /// A section in a [`MachOFile64`](super::MachOFile64). pubtype MachOSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
MachOSection<'data, 'file, macho::MachHeader64<Endian>, R>;
/// A section in a [`MachOFile`]. /// /// Most functionality is provided by the [`ObjectSection`] trait implementation. #[derive(Debug)] pubstruct MachOSection<'data, 'file, Mach, R = &'data [u8]> where
Mach: MachHeader,
R: ReadRef<'data>,
{ pub(super) file: &'file MachOFile<'data, Mach, R>, pub(super) internal: MachOSectionInternal<'data, Mach, R>,
}
impl<'data, 'file, Mach, R> MachOSection<'data, 'file, Mach, R> where
Mach: MachHeader,
R: ReadRef<'data>,
{ /// Get the Mach-O file containing this section. pubfn macho_file(&self) -> &'file MachOFile<'data, Mach, R> { self.file
}
/// Get the raw Mach-O section structure. pubfn macho_section(&self) -> &'data Mach::Section { self.internal.section
}
/// Get the raw Mach-O relocation entries. pubfn macho_relocations(&self) -> Result<&'data [macho::Relocation<Mach::Endian>]> { self.internal
.section
.relocations(self.file.endian, self.internal.data)
}
#[derive(Debug, Clone, Copy)] pub(super) struct MachOSectionInternal<'data, Mach: MachHeader, R: ReadRef<'data>> { pub index: SectionIndex, pub kind: SectionKind, pub section: &'data Mach::Section, /// The data for the file that contains the section data. /// /// This is required for dyld caches, where this may be a different subcache /// from the file containing the Mach-O load commands. pub data: R,
}
/// A trait for generic access to [`macho::Section32`] and [`macho::Section64`]. #[allow(missing_docs)] pubtrait Section: Debug + Pod { type Word: Into<u64>; type Endian: endian::Endian;
/// Return the `sectname` bytes up until the null terminator. fn name(&self) -> &[u8] { let sectname = &self.sectname()[..]; match memchr::memchr(b'\0', sectname) {
Some(end) => §name[..end],
None => sectname,
}
}
/// Return the `segname` bytes up until the null terminator. fn segment_name(&self) -> &[u8] { let segname = &self.segname()[..]; match memchr::memchr(b'\0', segname) {
Some(end) => &segname[..end],
None => segname,
}
}
/// Return the offset and size of the section in the file. /// /// Returns `None` for sections that have no data in the file. fn file_range(&self, endian: Self::Endian) -> Option<(u64, u64)> { matchself.flags(endian) & macho::SECTION_TYPE {
macho::S_ZEROFILL | macho::S_GB_ZEROFILL | macho::S_THREAD_LOCAL_ZEROFILL => None,
_ => Some((self.offset(endian).into(), self.size(endian).into())),
}
}
/// Return the section data. /// /// Returns `Ok(&[])` if the section has no data. /// Returns `Err` for invalid values. fn data<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> result::Result<&'data [u8], ()> { iflet Some((offset, size)) = self.file_range(endian) {
data.read_bytes_at(offset, size)
} else {
Ok(&[])
}
}
/// Return the relocation array. /// /// Returns `Err` for invalid values. fn relocations<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
data: R,
) -> Result<&'data [macho::Relocation<Self::Endian>]> {
data.read_slice_at(self.reloff(endian).into(), self.nreloc(endian) as usize)
.read_error("Invalid Mach-O relocations offset or number")
}
}
impl<Endian: endian::Endian> Section for macho::Section32<Endian> { type Word = u32; type Endian = Endian;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.