LCOV - code coverage report
Current view: top level - src/macho - header.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 40.4 % 171 69
Test Date: 2025-08-10:00:00:00 Functions: 54.5 % 33 18

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : 
       3              : use bitflags::bitflags;
       4              : 
       5              : use std::{fmt, marker::PhantomData};
       6              : use crate::common::FromFFI;
       7              : 
       8              : #[allow(non_camel_case_types)]
       9          360 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
      10              : pub enum FileType {
      11              :     OBJECT,
      12              :     EXECUTE,
      13              :     FVMLIB,
      14              :     CORE,
      15              :     PRELOAD,
      16              :     DYLIB,
      17              :     DYLINKER,
      18              :     BUNDLE,
      19              :     DYLIB_STUB,
      20              :     DSYM,
      21              :     KEXT_BUNDLE,
      22              :     FILESET,
      23              :     GPU_EXECUTE,
      24              :     GPU_DYLIB,
      25              :     UNKNOWN(u32),
      26              : }
      27              : 
      28              : impl From<u32> for FileType {
      29          360 :     fn from(value: u32) -> Self {
      30          360 :         match value {
      31           12 :             0x00000001 => FileType::OBJECT,
      32           48 :             0x00000002 => FileType::EXECUTE,
      33            0 :             0x00000003 => FileType::FVMLIB,
      34            0 :             0x00000004 => FileType::CORE,
      35            0 :             0x00000005 => FileType::PRELOAD,
      36          120 :             0x00000006 => FileType::DYLIB,
      37            0 :             0x00000007 => FileType::DYLINKER,
      38            0 :             0x00000008 => FileType::BUNDLE,
      39            0 :             0x00000009 => FileType::DYLIB_STUB,
      40            0 :             0x0000000a => FileType::DSYM,
      41            0 :             0x0000000b => FileType::KEXT_BUNDLE,
      42            0 :             0x0000000c => FileType::FILESET,
      43          180 :             0x0000000d => FileType::GPU_EXECUTE,
      44            0 :             0x0000000e => FileType::GPU_DYLIB,
      45            0 :             _ => FileType::UNKNOWN(value),
      46              : 
      47              :         }
      48          360 :     }
      49              : }
      50              : impl From<FileType> for u32 {
      51            0 :     fn from(value: FileType) -> u32 {
      52            0 :         match value {
      53            0 :             FileType::OBJECT => 0x00000001,
      54            0 :             FileType::EXECUTE => 0x00000002,
      55            0 :             FileType::FVMLIB => 0x00000003,
      56            0 :             FileType::CORE => 0x00000004,
      57            0 :             FileType::PRELOAD => 0x00000005,
      58            0 :             FileType::DYLIB => 0x00000006,
      59            0 :             FileType::DYLINKER => 0x00000007,
      60            0 :             FileType::BUNDLE => 0x00000008,
      61            0 :             FileType::DYLIB_STUB => 0x00000009,
      62            0 :             FileType::DSYM => 0x0000000a,
      63            0 :             FileType::KEXT_BUNDLE => 0x0000000b,
      64            0 :             FileType::FILESET => 0x0000000c,
      65            0 :             FileType::GPU_EXECUTE => 0x0000000d,
      66            0 :             FileType::GPU_DYLIB => 0x0000000e,
      67            0 :             FileType::UNKNOWN(value) => value,
      68              :         }
      69            0 :     }
      70              : }
      71              : 
      72              : 
      73              : #[allow(non_camel_case_types)]
      74          360 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
      75              : pub enum CpuType {
      76              :     ANY,
      77              :     X86,
      78              :     X86_64,
      79              :     MIPS,
      80              :     MC98000,
      81              :     HPPA,
      82              :     ARM,
      83              :     ARM64,
      84              :     MC88000,
      85              :     SPARC,
      86              :     I860,
      87              :     ALPHA,
      88              :     POWERPC,
      89              :     POWERPC64,
      90              :     APPLE_GPU,
      91              :     AMD_GPU,
      92              :     INTEL_GPU,
      93              :     AIR64,
      94              :     UNKNOWN(i32),
      95              : }
      96              : 
      97              : impl From<i32> for CpuType {
      98          360 :     fn from(value: i32) -> Self {
      99          360 :         match value {
     100            0 :             -1 => CpuType::ANY,
     101           24 :             0x00000007 => CpuType::X86,
     102           48 :             0x01000007 => CpuType::X86_64,
     103            0 :             0x00000008 => CpuType::MIPS,
     104            0 :             0x0000000a => CpuType::MC98000,
     105            0 :             0x0000000b => CpuType::HPPA,
     106           24 :             0x0000000c => CpuType::ARM,
     107           84 :             0x0100000c => CpuType::ARM64,
     108            0 :             0x0000000d => CpuType::MC88000,
     109            0 :             0x0000000e => CpuType::SPARC,
     110            0 :             0x0000000f => CpuType::I860,
     111            0 :             0x00000010 => CpuType::ALPHA,
     112            0 :             0x00000012 => CpuType::POWERPC,
     113            0 :             0x01000012 => CpuType::POWERPC64,
     114          180 :             0x01000013 => CpuType::APPLE_GPU,
     115            0 :             0x01000014 => CpuType::AMD_GPU,
     116            0 :             0x01000015 => CpuType::INTEL_GPU,
     117            0 :             0x01000017 => CpuType::AIR64,
     118            0 :             _ => CpuType::UNKNOWN(value),
     119              : 
     120              :         }
     121          360 :     }
     122              : }
     123              : impl From<CpuType> for i32 {
     124            0 :     fn from(value: CpuType) -> i32 {
     125            0 :         match value {
     126            0 :             CpuType::ANY => -1,
     127            0 :             CpuType::X86 => 0x00000007,
     128            0 :             CpuType::X86_64 => 0x01000007,
     129            0 :             CpuType::MIPS => 0x00000008,
     130            0 :             CpuType::MC98000 => 0x0000000a,
     131            0 :             CpuType::HPPA => 0x0000000b,
     132            0 :             CpuType::ARM => 0x0000000c,
     133            0 :             CpuType::ARM64 => 0x0100000c,
     134            0 :             CpuType::MC88000 => 0x0000000d,
     135            0 :             CpuType::SPARC => 0x0000000e,
     136            0 :             CpuType::I860 => 0x0000000f,
     137            0 :             CpuType::ALPHA => 0x00000010,
     138            0 :             CpuType::POWERPC => 0x00000012,
     139            0 :             CpuType::POWERPC64 => 0x01000012,
     140            0 :             CpuType::APPLE_GPU => 0x01000013,
     141            0 :             CpuType::AMD_GPU => 0x01000014,
     142            0 :             CpuType::INTEL_GPU => 0x01000015,
     143            0 :             CpuType::AIR64 => 0x01000017,
     144            0 :             CpuType::UNKNOWN(_) => -1,
     145              :         }
     146            0 :     }
     147              : }
     148              : 
     149              : 
     150            0 : bitflags! {
     151          360 :     #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     152            0 :     pub struct Flags: u32 {
     153            0 :         const NOUNDEFS = 0x1;
     154            0 :         const INCRLINK = 0x2;
     155            0 :         const DYLDLINK = 0x4;
     156            0 :         const BINDATLOAD = 0x8;
     157            0 :         const PREBOUND = 0x10;
     158            0 :         const SPLIT_SEGS = 0x20;
     159            0 :         const LAZY_INIT = 0x40;
     160            0 :         const TWOLEVEL = 0x80;
     161            0 :         const FORCE_FLAT = 0x100;
     162            0 :         const NOMULTIDEFS = 0x200;
     163            0 :         const NOFIXPREBINDING = 0x400;
     164            0 :         const PREBINDABLE = 0x800;
     165            0 :         const ALLMODSBOUND = 0x1000;
     166            0 :         const SUBSECTIONS_VIA_SYMBOLS = 0x2000;
     167            0 :         const CANONICAL = 0x4000;
     168            0 :         const WEAK_DEFINES = 0x8000;
     169            0 :         const BINDS_TO_WEAK = 0x10000;
     170            0 :         const ALLOW_STACK_EXECUTION = 0x20000;
     171            0 :         const ROOT_SAFE = 0x40000;
     172            0 :         const SETUID_SAFE = 0x80000;
     173            0 :         const NO_REEXPORTED_DYLIBS = 0x100000;
     174            0 :         const PIE = 0x200000;
     175            0 :         const DEAD_STRIPPABLE_DYLIB = 0x400000;
     176            0 :         const HAS_TLV_DESCRIPTORS = 0x800000;
     177            0 :         const NO_HEAP_EXECUTION = 0x1000000;
     178            0 :         const APP_EXTENSION_SAFE = 0x2000000;
     179            0 :         const NLIST_OUTOFSYNC_WITH_DYLDINFO = 0x04000000;
     180            0 :         const SIM_SUPPORT = 0x08000000;
     181            0 :         const IMPLICIT_PAGEZERO = 0x10000000;
     182            0 :         const DYLIB_IN_CACHE = 0x80000000;
     183            0 :     }
     184            0 : }
     185              : 
     186              : 
     187              : impl From<u32> for Flags {
     188          360 :     fn from(value: u32) -> Self {
     189          360 :         Flags::from_bits_truncate(value)
     190          360 :     }
     191              : }
     192              : impl From<Flags> for u32 {
     193            0 :     fn from(value: Flags) -> Self {
     194            0 :         value.bits()
     195            0 :     }
     196              : }
     197              : 
     198              : /// Structure that represents the main Mach-O header (at the beginning of the file)
     199              : pub struct Header<'a> {
     200              :     ptr: cxx::UniquePtr<ffi::MachO_Header>,
     201              :     _owner: PhantomData<&'a ffi::MachO_Binary>
     202              : }
     203              : 
     204              : impl FromFFI<ffi::MachO_Header> for Header<'_> {
     205         1080 :     fn from_ffi(hdr: cxx::UniquePtr<ffi::MachO_Header>) -> Self {
     206         1080 :         Self {
     207         1080 :             ptr: hdr,
     208         1080 :             _owner: PhantomData
     209         1080 :         }
     210         1080 :     }
     211              : }
     212              : 
     213              : impl Header<'_> {
     214              :     /// The Mach-O magic bytes. These bytes determine whether it is
     215              :     /// a 32 bits Mach-O, a 64 bits Mach-O files etc.
     216          360 :     pub fn magic(&self) -> u32 {
     217          360 :         self.ptr.magic()
     218          360 :     }
     219              : 
     220              :     /// The CPU architecture targeted by this binary
     221          360 :     pub fn cpu_type(&self) -> CpuType {
     222          360 :         CpuType::from(self.ptr.cpu_type())
     223          360 :     }
     224              : 
     225              :     /// Return the CPU subtype supported by the Mach-O binary.
     226              :     /// For ARM architectures, this value could represent the minimum version
     227              :     /// for which the Mach-O binary has been compiled for.
     228          360 :     pub fn cpu_subtype(&self) -> u32 {
     229          360 :         self.ptr.cpu_subtype()
     230          360 :     }
     231              : 
     232              :     /// Return the type of the Mach-O file (executable, object, shared library, ...)
     233          360 :     pub fn file_type(&self) -> FileType {
     234          360 :         FileType::from(self.ptr.file_type())
     235          360 :     }
     236              : 
     237              :     /// Number of [`crate::macho::Commands`] present in the Mach-O binary
     238          360 :     pub fn nb_cmds(&self) -> u32 {
     239          360 :         self.ptr.nb_cmds()
     240          360 :     }
     241              : 
     242              :     /// The raw size of **all** the load commands (`LC_xxx`)
     243          360 :     pub fn sizeof_cmds(&self) -> u32 {
     244          360 :         self.ptr.sizeof_cmds()
     245          360 :     }
     246              : 
     247              :     /// Header flags
     248          360 :     pub fn flags(&self) -> Flags {
     249          360 :         Flags::from(self.ptr.flags())
     250          360 :     }
     251              : 
     252              :     /// According to the official specs, a reserved value
     253          360 :     pub fn reserved(&self) -> u32 {
     254          360 :         self.ptr.reserved()
     255          360 :     }
     256              : 
     257              :     /// True if the binary is 32-bit
     258          360 :     pub fn is_32bit(&self) -> bool {
     259          360 :         self.ptr.is_32bit()
     260          360 :     }
     261              : 
     262              :     /// True if the binary is 64-bit
     263          360 :     pub fn is_64bit(&self) -> bool {
     264          360 :         self.ptr.is_64bit()
     265          360 :     }
     266              : }
     267              : 
     268              : impl fmt::Debug for Header<'_> {
     269          360 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     270          360 :         f.debug_struct("Header")
     271          360 :             .field("magic", &self.magic())
     272          360 :             .field("cpu_type", &self.cpu_type())
     273          360 :             .field("cpu_subtype", &self.cpu_subtype())
     274          360 :             .field("file_type", &self.file_type())
     275          360 :             .field("nb_cmds", &self.nb_cmds())
     276          360 :             .field("sizeof_cmds", &self.sizeof_cmds())
     277          360 :             .field("flags", &self.flags())
     278          360 :             .field("reserved", &self.reserved())
     279          360 :             .finish()
     280          360 :     }
     281              : }
        

Generated by: LCOV version 2.1-1