LCOV - code coverage report
Current view: top level - src/macho - binary.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 46.2 % 385 178
Test Date: 2026-04-12:00:00:00 Functions: 48.1 % 108 52

            Line data    Source code
       1              : use num_traits::{cast, Num};
       2              : use std::mem::size_of;
       3              : use std::path::Path;
       4              : use std::pin::Pin;
       5              : 
       6              : use super::binding_info::BindingInfo;
       7              : use super::builder::Config;
       8              : use super::commands::atom_info::AtomInfo;
       9              : use super::commands::build_version::{BuildVersion, Platform};
      10              : use super::commands::code_signature::CodeSignature;
      11              : use super::commands::code_signature_dir::CodeSignatureDir;
      12              : use super::commands::data_in_code::DataInCode;
      13              : use super::commands::dyld_chained_fixups::DyldChainedFixups;
      14              : use super::commands::dyld_environment::DyldEnvironment;
      15              : use super::commands::dyld_export_trie::DyldExportsTrie;
      16              : use super::commands::dyldinfo::DyldInfo;
      17              : use super::commands::dylib::Libraries;
      18              : use super::commands::dylinker::Dylinker;
      19              : use super::commands::dynamic_symbol_command::DynamicSymbolCommand;
      20              : use super::commands::encryption_info::EncryptionInfo;
      21              : use super::commands::function_variant_fixups::FunctionVariantFixups;
      22              : use super::commands::function_variants::FunctionVariants;
      23              : use super::commands::functionstarts::FunctionStarts;
      24              : use super::commands::linker_opt_hint::LinkerOptHint;
      25              : use super::commands::main_cmd::Main;
      26              : use super::commands::note::Note;
      27              : use super::commands::routine::Routine;
      28              : use super::commands::rpath::RPath;
      29              : use super::commands::rpath::RPaths;
      30              : use super::commands::segment::{Segment, Segments};
      31              : use super::commands::segment_split_info::SegmentSplitInfo;
      32              : use super::commands::source_version::SourceVersion;
      33              : use super::commands::sub_client::SubClients;
      34              : use super::commands::sub_framework::SubFramework;
      35              : use super::commands::symbol_command::SymbolCommand;
      36              : use super::commands::thread_command::ThreadCommand;
      37              : use super::commands::two_level_hints::TwoLevelHints;
      38              : use super::commands::uuid::UUID;
      39              : use super::commands::version_min::VersionMin;
      40              : use super::commands::{Command, Commands, CommandsIter, Dylib, LoadCommandTypes};
      41              : use super::export_info::ExportInfo;
      42              : use super::header::Header;
      43              : use super::relocation::Relocations;
      44              : use super::section::{Section, Sections};
      45              : use super::stub::Stub;
      46              : use super::symbol::{Symbol, Symbols};
      47              : use crate::Error;
      48              : use lief_ffi as ffi;
      49              : 
      50              : use crate::common::{into_optional, AsFFI, FromFFI};
      51              : use crate::objc::Metadata;
      52              : use crate::{declare_fwd_iterator, declare_iterator, generic, to_conv_result, to_result, to_slice};
      53              : 
      54              : /// This is the main interface to read and write Mach-O binary attributes.
      55              : ///
      56              : /// Note that this structure implements the [`generic::Binary`] trait from which other generic
      57              : /// functions are exposed
      58              : pub struct Binary {
      59              :     ptr: cxx::UniquePtr<ffi::MachO_Binary>,
      60              : }
      61              : 
      62              : impl std::fmt::Debug for Binary {
      63          416 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      64          416 :         f.debug_struct("Binary").finish()
      65          416 :     }
      66              : }
      67              : 
      68              : impl FromFFI<ffi::MachO_Binary> for Binary {
      69         4355 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::MachO_Binary>) -> Self {
      70         4355 :         Binary { ptr }
      71         4355 :     }
      72              : }
      73              : 
      74              : impl Binary {
      75              :     /// Return the main Mach-O header
      76         1248 :     pub fn header(&self) -> Header<'_> {
      77         1248 :         Header::from_ffi(self.ptr.header())
      78         1248 :     }
      79              : 
      80              :     /// Return an iterator over the different [`crate::macho::Commands`] used by the
      81              :     /// Mach-O binary
      82          416 :     pub fn commands(&self) -> CommandsIter<'_> {
      83          416 :         CommandsIter::new(self.ptr.commands())
      84          416 :     }
      85              : 
      86              :     /// Return an iterator over the different [`crate::macho::Section`] of the binary
      87          429 :     pub fn sections(&self) -> Sections<'_> {
      88          429 :         Sections::new(self.ptr.sections())
      89          429 :     }
      90              : 
      91              :     /// Return an iterator over the different [`crate::macho::commands::Segment`] (`LC_SEGMENT/LC_SIGNATURE`)
      92              :     /// of the binary.
      93          416 :     pub fn segments(&self) -> Segments<'_> {
      94          416 :         Segments::new(self.ptr.segments())
      95          416 :     }
      96              : 
      97              :     /// Return an iterator over the [`crate::macho::commands::Dylib`] used by this binary
      98          416 :     pub fn libraries(&self) -> Libraries<'_> {
      99          416 :         Libraries::new(self.ptr.libraries())
     100          416 :     }
     101              : 
     102              :     /// Return an iterator over the different [`crate::macho::Relocation`] of this binary
     103          416 :     pub fn relocations(&self) -> Relocations<'_> {
     104          416 :         Relocations::new(self.ptr.relocations())
     105          416 :     }
     106              : 
     107              :     /// Return an iterator over the different [`crate::macho::commands::RPath`] of this binary
     108            0 :     pub fn rpaths(&self) -> RPaths<'_> {
     109            0 :         RPaths::new(self.ptr.rpaths())
     110            0 :     }
     111              : 
     112              :     /// Return an iterator over the different [`crate::macho::Symbol`] of this binary
     113          416 :     pub fn symbols(&self) -> Symbols<'_> {
     114          416 :         Symbols::new(self.ptr.symbols())
     115          416 :     }
     116              : 
     117              :     /// Return the `LC_DYLD_INFO/LC_DYLD_INFO_ONLY` command if present
     118          416 :     pub fn dyld_info(&self) -> Option<DyldInfo<'_>> {
     119          416 :         into_optional(self.ptr.dyld_info())
     120          416 :     }
     121              : 
     122              :     /// Return the `LC_UUID` command if present
     123          416 :     pub fn uuid(&self) -> Option<UUID<'_>> {
     124          416 :         into_optional(self.ptr.uuid())
     125          416 :     }
     126              : 
     127              :     /// Return the `LC_MAIN` command if present
     128          416 :     pub fn main_command(&self) -> Option<Main<'_>> {
     129          416 :         into_optional(self.ptr.main_command())
     130          416 :     }
     131              : 
     132              :     /// Return the `LC_LOAD_DYLINKER/LC_ID_DYLINKER` command if present
     133          416 :     pub fn dylinker(&self) -> Option<Dylinker<'_>> {
     134          416 :         into_optional(self.ptr.dylinker())
     135          416 :     }
     136              : 
     137              :     /// Return the `LC_FUNCTION_STARTS` command if present
     138          416 :     pub fn function_starts(&self) -> Option<FunctionStarts<'_>> {
     139          416 :         into_optional(self.ptr.function_starts())
     140          416 :     }
     141              : 
     142              :     /// Return the `LC_SOURCE_VERSION` command if present
     143          416 :     pub fn source_version(&self) -> Option<SourceVersion<'_>> {
     144          416 :         into_optional(self.ptr.source_version())
     145          416 :     }
     146              : 
     147              :     /// Return the `LC_THREAD/LC_UNIXTHREAD` command if present
     148          416 :     pub fn thread_command(&self) -> Option<ThreadCommand<'_>> {
     149          416 :         into_optional(self.ptr.thread_command())
     150          416 :     }
     151              : 
     152              :     /// Return the `LC_RPATH` command if present
     153          416 :     pub fn rpath(&self) -> Option<RPath<'_>> {
     154          416 :         into_optional(self.ptr.rpath())
     155          416 :     }
     156              : 
     157              :     /// Return the `LC_ROUTINE/LC_ROUTINE64` command if present
     158          416 :     pub fn routine(&self) -> Option<Routine<'_>> {
     159          416 :         into_optional(self.ptr.routine_command())
     160          416 :     }
     161              : 
     162              :     /// Return the `LC_SYMTAB` command if present
     163          416 :     pub fn symbol_command(&self) -> Option<SymbolCommand<'_>> {
     164          416 :         into_optional(self.ptr.symbol_command())
     165          416 :     }
     166              : 
     167              :     /// Return the `LC_DYSYMTAB` command if present
     168          416 :     pub fn dynamic_symbol(&self) -> Option<DynamicSymbolCommand<'_>> {
     169          416 :         into_optional(self.ptr.dynamic_symbol_command())
     170          416 :     }
     171              : 
     172              :     /// Return the `LC_CODE_SIGNATURE` command if present
     173          416 :     pub fn code_signature(&self) -> Option<CodeSignature<'_>> {
     174          416 :         into_optional(self.ptr.code_signature())
     175          416 :     }
     176              : 
     177              :     /// Return the `LC_DYLIB_CODE_SIGN_DRS` command if present
     178          416 :     pub fn code_signature_dir(&self) -> Option<CodeSignatureDir<'_>> {
     179          416 :         into_optional(self.ptr.code_signature_dir())
     180          416 :     }
     181              : 
     182              :     /// Return the `LC_DATA_IN_CODE` command if present
     183          416 :     pub fn data_in_code(&self) -> Option<DataInCode<'_>> {
     184          416 :         into_optional(self.ptr.data_in_code())
     185          416 :     }
     186              : 
     187              :     /// Return the `LC_SEGMENT_SPLIT_INFO` command if present
     188          416 :     pub fn segment_split_info(&self) -> Option<SegmentSplitInfo<'_>> {
     189          416 :         into_optional(self.ptr.segment_split_info())
     190          416 :     }
     191              : 
     192              :     /// Return the `LC_ENCRYPTION_INFO/LC_ENCRYPTION_INFO_64` command if present
     193          416 :     pub fn encryption_info(&self) -> Option<EncryptionInfo<'_>> {
     194          416 :         into_optional(self.ptr.encryption_info())
     195          416 :     }
     196              : 
     197              :     /// Return the `LC_SUB_FRAMEWORK` command if present
     198          416 :     pub fn sub_framework(&self) -> Option<SubFramework<'_>> {
     199          416 :         into_optional(self.ptr.sub_framework())
     200          416 :     }
     201              : 
     202              :     /// Return the `LC_SUBCLIENT` command if present
     203          416 :     pub fn subclients(&self) -> SubClients<'_> {
     204          416 :         SubClients::new(self.ptr.subclients())
     205          416 :     }
     206              : 
     207              :     /// Return the `LC_DYLD_ENVIRONMENT` command if present
     208          416 :     pub fn dyld_environment(&self) -> Option<DyldEnvironment<'_>> {
     209          416 :         into_optional(self.ptr.dyld_environment())
     210          416 :     }
     211              : 
     212              :     /// Return the `LC_BUILD_VERSION` command if present
     213          416 :     pub fn build_version(&self) -> Option<BuildVersion<'_>> {
     214          416 :         into_optional(self.ptr.build_version())
     215          416 :     }
     216              : 
     217              :     /// Return the `LC_DYLD_CHAINED_FIXUPS` command if present
     218          416 :     pub fn dyld_chained_fixups(&self) -> Option<DyldChainedFixups<'_>> {
     219          416 :         into_optional(self.ptr.dyld_chained_fixups())
     220          416 :     }
     221              : 
     222              :     /// Return the `LC_DYLD_EXPORTS_TRIE` command if present
     223          416 :     pub fn dyld_exports_trie(&self) -> Option<DyldExportsTrie<'_>> {
     224          416 :         into_optional(self.ptr.dyld_exports_trie())
     225          416 :     }
     226              : 
     227              :     /// Return the `LC_TWOLEVEL_HINTS` command if present
     228          416 :     pub fn two_level_hints(&self) -> Option<TwoLevelHints<'_>> {
     229          416 :         into_optional(self.ptr.two_level_hints())
     230          416 :     }
     231              : 
     232              :     /// Return the `LC_LINKER_OPTIMIZATION_HINT` command if present
     233          416 :     pub fn linker_opt_hint(&self) -> Option<LinkerOptHint<'_>> {
     234          416 :         into_optional(self.ptr.linker_opt_hint())
     235          416 :     }
     236              : 
     237              :     /// Return the `LC_ATOM_INFO` command if present
     238            0 :     pub fn atom_info(&self) -> Option<AtomInfo<'_>> {
     239            0 :         into_optional(self.ptr.atom_info())
     240            0 :     }
     241              : 
     242              :     /// Return the `LC_FUNCTION_VARIANTS` command if present
     243            0 :     pub fn function_variants(&self) -> Option<FunctionVariants<'_>> {
     244            0 :         into_optional(self.ptr.function_variants())
     245            0 :     }
     246              : 
     247              :     /// Return the `LC_FUNCTION_VARIANT_FIXUPS` command if present
     248            0 :     pub fn function_variant_fixups(&self) -> Option<FunctionVariantFixups<'_>> {
     249            0 :         into_optional(self.ptr.function_variant_fixups())
     250            0 :     }
     251              : 
     252              :     /// Return the `LC_VERSION_MIN_MACOSX/VERSION_MIN_IPHONEOS` command if present
     253          416 :     pub fn version_min(&self) -> Option<VersionMin<'_>> {
     254          416 :         into_optional(self.ptr.version_min())
     255          416 :     }
     256              : 
     257              :     /// Check if the binary is supporting ARM64 pointer authentication (arm64e)
     258            0 :     pub fn support_arm64_ptr_auth(&self) -> bool {
     259            0 :         self.ptr.support_arm64_ptr_auth()
     260            0 :     }
     261              : 
     262              :     /// Return an iterator over the bindings located in [`DyldInfo`] or [`DyldChainedFixups`]
     263          416 :     pub fn bindings(&self) -> BindingsInfo<'_> {
     264          416 :         BindingsInfo::new(self.ptr.bindings())
     265          416 :     }
     266              : 
     267              :     /// Return an iterator over the symbol stubs.
     268              :     ///
     269              :     /// These stubs are involved when calling an **imported** function and are
     270              :     /// similar to the ELF's plt/got mechanism.
     271              :     ///
     272              :     /// There are located in sections like: `__stubs,__auth_stubs,__symbol_stub,__picsymbolstub4`
     273          416 :     pub fn symbol_stubs(&self) -> Stubs<'_> {
     274          416 :         Stubs::new(self.ptr.symbol_stubs())
     275          416 :     }
     276              : 
     277              :     /// Return Objective-C metadata if present
     278            0 :     pub fn objc_metadata(&self) -> Option<Metadata<'_>> {
     279            0 :         into_optional(self.ptr.objc_metadata())
     280            0 :     }
     281              : 
     282              :     /// Return the platform for which this Mach-O has been compiled
     283          416 :     pub fn platform(&self) -> Platform {
     284          416 :         Platform::from(self.ptr.platform())
     285          416 :     }
     286              : 
     287              :     /// True if this binary targets iOS
     288          416 :     pub fn is_ios(&self) -> bool {
     289          416 :         self.ptr.is_ios()
     290          416 :     }
     291              : 
     292              :     /// True if this binary targets macOS
     293          416 :     pub fn is_macos(&self) -> bool {
     294          416 :         self.ptr.is_macos()
     295          416 :     }
     296              : 
     297              :     /// Try to find the library with the given library name.
     298              :     ///
     299              :     /// This function tries to match the fullpath of the DylibCommand or the
     300              :     /// library name suffix.
     301            0 :     pub fn find_library(&self, name: &str) -> Option<Dylib<'_>> {
     302            0 :         into_optional(self.ptr.find_library(name.to_string()))
     303            0 :     }
     304              : 
     305              :     /// Get the integer value at the given virtual address
     306            0 :     pub fn get_int_from_virtual_address<T>(&self, addr: u64) -> Result<T, Error>
     307            0 :     where
     308            0 :         T: Num + cast::FromPrimitive + cast::ToPrimitive,
     309            0 :     {
     310            0 :         // Can't be in the generic trait because of:
     311            0 :         //   > for a trait to be "object safe" it needs to allow building a vtable to allow the call
     312            0 :         //   > to be resolvable dynamically; for more information visit
     313            0 :         //   > https://doc.rust-lang.org/reference/items/traits.html#object-safety
     314            0 :         if size_of::<T>() == size_of::<u8>() {
     315            0 :             to_conv_result!(
     316            0 :                 ffi::AbstractBinary::get_u8,
     317            0 :                 self.ptr.as_ref().unwrap().as_ref(),
     318            0 :                 |value| {
     319            0 :                     T::from_u8(value).unwrap_or_else(|| panic!("Can't cast value: {value}"))
     320            0 :                 },
     321            0 :                 addr
     322              :             );
     323            0 :         }
     324            0 : 
     325            0 :         if size_of::<T>() == size_of::<u16>() {
     326            0 :             to_conv_result!(
     327            0 :                 ffi::AbstractBinary::get_u16,
     328            0 :                 self.ptr.as_ref().unwrap().as_ref(),
     329            0 :                 |value| {
     330            0 :                     T::from_u16(value).unwrap_or_else(|| panic!("Can't cast value: {value}"))
     331            0 :                 },
     332            0 :                 addr
     333              :             );
     334            0 :         }
     335            0 : 
     336            0 :         if size_of::<T>() == size_of::<u32>() {
     337            0 :             to_conv_result!(
     338            0 :                 ffi::AbstractBinary::get_u32,
     339            0 :                 self.ptr.as_ref().unwrap().as_ref(),
     340            0 :                 |value| {
     341            0 :                     T::from_u32(value).unwrap_or_else(|| panic!("Can't cast value: {value}"))
     342            0 :                 },
     343            0 :                 addr
     344              :             );
     345            0 :         }
     346            0 : 
     347            0 :         if size_of::<T>() == size_of::<u64>() {
     348            0 :             to_conv_result!(
     349            0 :                 ffi::AbstractBinary::get_u64,
     350            0 :                 self.ptr.as_ref().unwrap().as_ref(),
     351            0 :                 |value| {
     352            0 :                     T::from_u64(value).unwrap_or_else(|| panic!("Can't cast value: {value}"))
     353            0 :                 },
     354            0 :                 addr
     355              :             );
     356            0 :         }
     357            0 : 
     358            0 :         Err(Error::NotSupported)
     359            0 :     }
     360              : 
     361              :     /// Write back the current MachO binary into the file specified in parameter
     362            2 :     pub fn write<P: AsRef<Path>>(&mut self, output: P) {
     363            2 :         self.ptr
     364            2 :             .as_mut()
     365            2 :             .unwrap()
     366            2 :             .write(output.as_ref().to_str().unwrap());
     367            2 :     }
     368              : 
     369              :     /// Write back the current MachO binary into the file specified in parameter with the
     370              :     /// configuration provided in the second parameter.
     371            1 :     pub fn write_with_config<P: AsRef<Path>>(&mut self, output: P, config: Config) {
     372            1 :         self.ptr
     373            1 :             .as_mut()
     374            1 :             .unwrap()
     375            1 :             .write_with_config(output.as_ref().to_str().unwrap(), config.to_ffi());
     376            1 :     }
     377              : 
     378              :     /// Insert a new command
     379            0 :     pub fn add_command(&mut self, command: impl Command) -> Option<Commands<'_>> {
     380            0 :         into_optional(self.ptr.as_mut().unwrap().add_command(command.get_base()))
     381            0 :     }
     382              : 
     383              :     /// Insert a new shared library through a `LC_LOAD_DYLIB` command
     384           26 :     pub fn add_library<'a>(&'a mut self, libname: &str) -> Dylib<'a> {
     385           26 :         Dylib::from_ffi(self.ptr.as_mut().unwrap().add_library(libname))
     386           26 :     }
     387              : 
     388              :     /// Remove all commands that have the given type
     389            0 :     pub fn remove_commands_by_type(&mut self, ty: LoadCommandTypes) -> bool {
     390            0 :         self.ptr
     391            0 :             .as_mut()
     392            0 :             .unwrap()
     393            0 :             .remove_commands_by_type(ty.into())
     394            0 :     }
     395              : 
     396          416 :     pub fn functions(&self) -> generic::Functions<'_> {
     397          416 :         generic::Functions::new(self.ptr.functions())
     398          416 :     }
     399              : 
     400              :     /// Return an iterator over the `LC_NOTE` commands
     401          416 :     pub fn notes(&self) -> Notes<'_> {
     402          416 :         Notes::new(self.ptr.notes())
     403          416 :     }
     404              : 
     405              :     /// Name associated with the `LC_FILESET_ENTRY` for this MachO.
     406              :     /// For instance: `com.apple.kec.corecrypto`
     407         3809 :     pub fn fileset_name(&self) -> String {
     408         3809 :         self.ptr.fileset_name().to_string()
     409         3809 :     }
     410              : 
     411              :     /// Original address associated with the `LC_FILESET_ENTRY` for this MachO.
     412         3809 :     pub fn fileset_addr(&self) -> u64 {
     413         3809 :         self.ptr.fileset_addr()
     414         3809 :     }
     415              : 
     416              :     /// Return an iterator over the [`Binary`] associated with the `LC_FILESET_ENTRY` commands
     417          416 :     pub fn filesets(&self) -> FilesetBinaries<'_> {
     418          416 :         FilesetBinaries::new(self.ptr.filesets())
     419          416 :     }
     420              : 
     421              :     /// Convert the given virtual address into an offset
     422            0 :     pub fn virtual_address_to_offset(&self, address: u64) -> Result<u64, Error> {
     423            0 :         to_result!(ffi::MachO_Binary::virtual_address_to_offset, &self, address);
     424            0 :     }
     425              :     /// Return the [`Segment`] associated with the given offset
     426            0 :     pub fn segment_from_offset(&self, offset: u64) -> Option<Segment<'_>> {
     427            0 :         into_optional(self.ptr.segment_from_offset(offset))
     428            0 :     }
     429              : 
     430              :     /// Return the [`Segment`] associated with the given virtual address
     431            0 :     pub fn segment_from_virtual_address(&self, va: u64) -> Option<Segment<'_>> {
     432            0 :         into_optional(self.ptr.segment_from_virtual_address(va))
     433            0 :     }
     434              : 
     435              :     /// Return the [`Section`] associated with the given virtual address
     436            0 :     pub fn section_from_virtual_address(&self, va: u64) -> Option<Section<'_>> {
     437            0 :         into_optional(self.ptr.section_from_virtual_address(va))
     438            0 :     }
     439              : 
     440              :     /// Return the [`Segment`] matching the given name
     441            0 :     pub fn get_segment(&self, name: String) -> Option<Segment<'_>> {
     442            0 :         into_optional(self.ptr.get_segment(name))
     443            0 :     }
     444              : 
     445              :     /// Return the [`Section`] embedded in the given segment's name
     446            0 :     pub fn get_section(&self, segment_name: String, section_name: String) -> Option<Section<'_>> {
     447            0 :         into_optional(self.ptr.get_section(segment_name, section_name))
     448            0 :     }
     449              : 
     450              :     /// Return the offset of this binary in the FAT binary
     451            0 :     pub fn fat_offset(&self) -> u64 {
     452            0 :         self.ptr.fat_offset()
     453            0 :     }
     454              : 
     455              :     /// Return the overlay data (if any)
     456            0 :     pub fn overlay(&self) -> &[u8] {
     457            0 :         to_slice!(self.ptr.overlay());
     458            0 :     }
     459              : 
     460              :     /// Return the TLV initial content range
     461            0 :     pub fn tlv_initial_content_range(&self) -> crate::Range {
     462            0 :         crate::Range::from_ffi(&self.ptr.tlv_initial_content_range())
     463            0 :     }
     464              : 
     465              :     /// Check if the given address is valid for this binary
     466            0 :     pub fn is_valid_addr(&self, address: u64) -> bool {
     467            0 :         self.ptr.is_valid_addr(address)
     468            0 :     }
     469              : 
     470              :     /// Check if the binary contains a symbol with the given name
     471            0 :     pub fn has_symbol(&self, name: &str) -> bool {
     472            0 :         self.ptr.has_symbol(name.to_string())
     473            0 :     }
     474              : 
     475              :     /// Return the symbol with the given name (if any)
     476            0 :     pub fn get_symbol(&self, name: &str) -> Option<Symbol<'_>> {
     477            0 :         into_optional(self.ptr.get_symbol(name.to_string()))
     478            0 :     }
     479              : 
     480              :     /// Check if the binary contains a section with the given name
     481            0 :     pub fn has_section(&self, name: &str) -> bool {
     482            0 :         self.ptr.has_section(name.to_string())
     483            0 :     }
     484              : 
     485              :     /// Return the [`Section`] associated with the given offset
     486            0 :     pub fn section_from_offset(&self, offset: u64) -> Option<Section<'_>> {
     487            0 :         into_optional(self.ptr.section_from_offset(offset))
     488            0 :     }
     489              : 
     490              :     /// Check if the binary contains a segment with the given name
     491            0 :     pub fn has_segment(&self, name: &str) -> bool {
     492            0 :         self.ptr.has_segment(name.to_string())
     493            0 :     }
     494              : 
     495              :     /// Check if the binary has a command with the given type
     496            0 :     pub fn has_command_type(&self, ty: LoadCommandTypes) -> bool {
     497            0 :         self.ptr.has_command_type(ty.into())
     498            0 :     }
     499              : 
     500              :     /// Get a command with the given type
     501            0 :     pub fn get_command_type(&self, ty: LoadCommandTypes) -> Option<Commands<'_>> {
     502            0 :         into_optional(self.ptr.get_command_type(ty.into()))
     503            0 :     }
     504              : 
     505              :     /// Remove the command at the given index
     506            0 :     pub fn remove_command(&mut self, index: u32) -> bool {
     507            0 :         self.ptr.as_mut().unwrap().remove_command(index)
     508            0 :     }
     509              : 
     510              :     /// Remove a section by name
     511            0 :     pub fn remove_section(&mut self, name: &str, clear: bool) {
     512            0 :         self.ptr
     513            0 :             .as_mut()
     514            0 :             .unwrap()
     515            0 :             .remove_section(name.to_string(), clear);
     516            0 :     }
     517              : 
     518              :     /// Remove a section by segment name and section name
     519            0 :     pub fn remove_section_from_segment(&mut self, segname: &str, secname: &str, clear: bool) {
     520            0 :         self.ptr.as_mut().unwrap().remove_section_seg(
     521            0 :             segname.to_string(),
     522            0 :             secname.to_string(),
     523            0 :             clear,
     524            0 :         );
     525            0 :     }
     526              : 
     527              :     /// Remove the `LC_CODE_SIGNATURE` command
     528            0 :     pub fn remove_signature(&mut self) -> bool {
     529            0 :         self.ptr.as_mut().unwrap().remove_signature()
     530            0 :     }
     531              : 
     532              :     /// Remove a symbol by name
     533            0 :     pub fn remove_symbol(&mut self, name: &str) -> bool {
     534            0 :         self.ptr.as_mut().unwrap().remove_symbol(name.to_string())
     535            0 :     }
     536              : 
     537              :     /// Check if the given symbol can be safely removed
     538            0 :     pub fn can_remove(&self, sym: &Symbol<'_>) -> bool {
     539            0 :         self.ptr.can_remove(sym.as_ffi())
     540            0 :     }
     541              : 
     542              :     /// Check if the symbol with the given name can be safely removed
     543            0 :     pub fn can_remove_symbol(&self, name: &str) -> bool {
     544            0 :         self.ptr.can_remove_symbol(name.to_string())
     545            0 :     }
     546              : 
     547              :     /// Unexport the symbol with the given name
     548            0 :     pub fn unexport_name(&mut self, name: &str) -> bool {
     549            0 :         self.ptr.as_mut().unwrap().unexport_name(name.to_string())
     550            0 :     }
     551              : 
     552              :     /// Unexport the given symbol
     553            0 :     pub fn unexport_symbol(&mut self, sym: &super::Symbol<'_>) -> bool {
     554            0 :         self.ptr.as_mut().unwrap().unexport_symbol(sym.as_ffi())
     555            0 :     }
     556              : 
     557              :     /// Add a new exported function
     558            0 :     pub fn add_exported_function(&mut self, address: u64, name: &str) -> Option<ExportInfo<'_>> {
     559            0 :         into_optional(
     560            0 :             self.ptr
     561            0 :                 .as_mut()
     562            0 :                 .unwrap()
     563            0 :                 .add_exported_function(address, name.to_string()),
     564            0 :         )
     565            0 :     }
     566              : 
     567              :     /// Add a new local symbol
     568            0 :     pub fn add_local_symbol(&mut self, address: u64, name: &str) -> Option<Symbol<'_>> {
     569            0 :         into_optional(
     570            0 :             self.ptr
     571            0 :                 .as_mut()
     572            0 :                 .unwrap()
     573            0 :                 .add_local_symbol(address, name.to_string()),
     574            0 :         )
     575            0 :     }
     576              : 
     577              :     /// Shift the content of the binary
     578            0 :     pub fn shift(&mut self, value: u64) -> Result<(), Error> {
     579            0 :         to_conv_result!(ffi::MachO_Binary::shift, self.ptr.pin_mut(), |_| (), value);
     580            0 :     }
     581              : 
     582              :     /// Shift the __LINKEDIT segment
     583            0 :     pub fn shift_linkedit(&mut self, width: u64) -> Result<(), Error> {
     584            0 :         to_conv_result!(
     585            0 :             ffi::MachO_Binary::shift_linkedit,
     586            0 :             self.ptr.pin_mut(),
     587            0 :             |_| (),
     588            0 :             width
     589              :         );
     590            0 :     }
     591              : }
     592              : 
     593              : impl AsFFI<ffi::MachO_Binary> for Binary {
     594            0 :     fn as_ffi(&self) -> &ffi::MachO_Binary {
     595            0 :         self.ptr.as_ref().unwrap()
     596            0 :     }
     597              : 
     598            0 :     fn as_mut_ffi(&mut self) -> std::pin::Pin<&mut ffi::MachO_Binary> {
     599            0 :         self.ptr.pin_mut()
     600            0 :     }
     601              : }
     602              : 
     603              : impl generic::Binary for Binary {
     604          416 :     fn as_generic(&self) -> &ffi::AbstractBinary {
     605          416 :         self.ptr.as_ref().unwrap().as_ref()
     606          416 :     }
     607              : 
     608            0 :     fn as_pin_mut_generic(&mut self) -> Pin<&mut ffi::AbstractBinary> {
     609            0 :         unsafe {
     610            0 :             Pin::new_unchecked({
     611            0 :                 (self.ptr.as_ref().unwrap().as_ref() as *const ffi::AbstractBinary
     612            0 :                     as *mut ffi::AbstractBinary)
     613            0 :                     .as_mut()
     614            0 :                     .unwrap()
     615            0 :             })
     616            0 :         }
     617            0 :     }
     618              : }
     619              : 
     620        90103 : declare_fwd_iterator!(
     621        90103 :     BindingsInfo,
     622        90103 :     BindingInfo<'a>,
     623        90103 :     ffi::MachO_BindingInfo,
     624        90103 :     ffi::MachO_Binary,
     625        90103 :     ffi::MachO_Binary_it_bindings_info
     626        90103 : );
     627              : 
     628        23478 : declare_iterator!(
     629        23478 :     Stubs,
     630        23478 :     Stub<'a>,
     631        23478 :     ffi::MachO_Stub,
     632        23478 :     ffi::MachO_Binary,
     633        23478 :     ffi::MachO_Binary_it_stubs
     634        23478 : );
     635              : 
     636         1560 : declare_iterator!(
     637         1560 :     Notes,
     638         1560 :     Note<'a>,
     639         1560 :     ffi::MachO_NoteCommand,
     640         1560 :     ffi::MachO_Binary,
     641         1560 :     ffi::MachO_Binary_it_notes
     642         1560 : );
     643              : 
     644         3809 : declare_iterator!(
     645         3809 :     FilesetBinaries,
     646         3809 :     Binary,
     647         3809 :     ffi::MachO_Binary,
     648         3809 :     ffi::MachO_Binary,
     649         3809 :     ffi::MachO_Binary_it_fileset_binaries
     650         3809 : );
        

Generated by: LCOV version 2.1-1