LCOV - code coverage report
Current view: top level - src/macho - section.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 72.5 % 131 95
Test Date: 2024-11-30:00:00:00 Functions: 63.6 % 33 21

            Line data    Source code
       1              : use super::commands::segment::Segment;
       2              : use super::Relocation;
       3              : use lief_ffi as ffi;
       4              : use std::fmt;
       5              : use std::marker::PhantomData;
       6              : 
       7              : use crate::common::{into_optional, FromFFI};
       8              : use crate::declare_iterator;
       9              : use crate::generic;
      10              : 
      11              : use bitflags::bitflags;
      12              : 
      13              : pub struct Section<'a> {
      14              :     ptr: cxx::UniquePtr<ffi::MachO_Section>,
      15              :     _owner: PhantomData<&'a ()>,
      16              : }
      17              : 
      18              : #[allow(non_camel_case_types)]
      19       212280 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
      20              : pub enum Type {
      21              :     /// Regular section.
      22              :     REGULAR,
      23              :     /// Zero fill on demand section.
      24              :     ZEROFILL,
      25              :     /// Section with literal C strings.
      26              :     CSTRING_LITERALS,
      27              :     /// Section with 4 byte literals.
      28              :     S_4BYTE_LITERALS,
      29              :     /// Section with 8 byte literals.
      30              :     S_8BYTE_LITERALS,
      31              :     /// Section with pointers to literals.
      32              :     LITERAL_POINTERS,
      33              :     /// Section with non-lazy symbol pointers.
      34              :     NON_LAZY_SYMBOL_POINTERS,
      35              :     /// Section with lazy symbol pointers.
      36              :     LAZY_SYMBOL_POINTERS,
      37              :     /// Section with symbol stubs, byte size of stub in the Reserved2 field.
      38              :     SYMBOL_STUBS,
      39              :     /// Section with only function pointers for initialization.
      40              :     MOD_INIT_FUNC_POINTERS,
      41              :     /// Section with only function pointers for termination.
      42              :     MOD_TERM_FUNC_POINTERS,
      43              :     /// Section contains symbols that are to be coalesced.
      44              :     COALESCED,
      45              :     /// Zero fill on demand section (that can be larger than 4 gigabytes).
      46              :     GB_ZEROFILL,
      47              :     /// Section with only pairs of function pointers for interposing.
      48              :     INTERPOSING,
      49              :     /// Section with only 16 byte literals.
      50              :     S_16BYTE_LITERALS,
      51              :     /// Section contains DTrace Object Format.
      52              :     DTRACE_DOF,
      53              :     /// Section with lazy symbol pointers to lazy loaded dylibs.
      54              :     LAZY_DYLIB_SYMBOL_POINTERS,
      55              :     /// Thread local data section.
      56              :     THREAD_LOCAL_REGULAR,
      57              :     /// Thread local zerofill section.
      58              :     THREAD_LOCAL_ZEROFILL,
      59              :     /// Section with thread local variable structure data.
      60              :     THREAD_LOCAL_VARIABLES,
      61              :     /// Section with pointers to thread local structures.
      62              :     THREAD_LOCAL_VARIABLE_POINTERS,
      63              :     /// Section with thread local variable initialization pointers to functions.
      64              :     THREAD_LOCAL_INIT_FUNCTION_POINTERS,
      65              :     /// Section with 32-bit offsets to initializer functions
      66              :     INIT_FUNC_OFFSETS,
      67              :     UNKNOWN(u64),
      68              : }
      69              : 
      70              : impl From<u64> for Type {
      71       212280 :     fn from(value: u64) -> Self {
      72       212280 :         match value {
      73       178350 :             0x00000000 => Type::REGULAR,
      74          480 :             0x00000001 => Type::ZEROFILL,
      75          440 :             0x00000002 => Type::CSTRING_LITERALS,
      76            0 :             0x00000003 => Type::S_4BYTE_LITERALS,
      77            0 :             0x00000004 => Type::S_8BYTE_LITERALS,
      78           60 :             0x00000005 => Type::LITERAL_POINTERS,
      79        16780 :             0x00000006 => Type::NON_LAZY_SYMBOL_POINTERS,
      80         7760 :             0x00000007 => Type::LAZY_SYMBOL_POINTERS,
      81         2320 :             0x00000008 => Type::SYMBOL_STUBS,
      82            0 :             0x00000009 => Type::MOD_INIT_FUNC_POINTERS,
      83            0 :             0x0000000a => Type::MOD_TERM_FUNC_POINTERS,
      84         6010 :             0x0000000b => Type::COALESCED,
      85            0 :             0x0000000c => Type::GB_ZEROFILL,
      86            0 :             0x0000000d => Type::INTERPOSING,
      87           20 :             0x0000000e => Type::S_16BYTE_LITERALS,
      88           40 :             0x0000000f => Type::DTRACE_DOF,
      89            0 :             0x00000010 => Type::LAZY_DYLIB_SYMBOL_POINTERS,
      90            0 :             0x00000011 => Type::THREAD_LOCAL_REGULAR,
      91            0 :             0x00000012 => Type::THREAD_LOCAL_ZEROFILL,
      92            0 :             0x00000013 => Type::THREAD_LOCAL_VARIABLES,
      93            0 :             0x00000014 => Type::THREAD_LOCAL_VARIABLE_POINTERS,
      94            0 :             0x00000015 => Type::THREAD_LOCAL_INIT_FUNCTION_POINTERS,
      95           20 :             0x00000016 => Type::INIT_FUNC_OFFSETS,
      96            0 :             _ => Type::UNKNOWN(value),
      97              :         }
      98       212280 :     }
      99              : }
     100              : 
     101              : 
     102            0 : bitflags! {
     103       212280 :     #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     104            0 :     pub struct Flags: u64 {
     105            0 :         const PURE_INSTRUCTIONS = 0x80000000;
     106            0 :         const NO_TOC = 0x40000000;
     107            0 :         const STRIP_STATIC_SYMS = 0x20000000;
     108            0 :         const NO_DEAD_STRIP = 0x10000000;
     109            0 :         const LIVE_SUPPORT = 0x8000000;
     110            0 :         const SELF_MODIFYING_CODE = 0x4000000;
     111            0 :         const DEBUG_INFO = 0x2000000;
     112            0 :         const SOME_INSTRUCTIONS = 0x400;
     113            0 :         const EXT_RELOC = 0x200;
     114            0 :         const LOC_RELOC = 0x100;
     115            0 :     }
     116            0 : }
     117              : 
     118              : 
     119              : impl From<u64> for Flags {
     120            0 :     fn from(value: u64) -> Self {
     121            0 :         Flags::from_bits_truncate(value)
     122            0 :     }
     123              : }
     124              : impl From<Flags> for u64 {
     125            0 :     fn from(value: Flags) -> Self {
     126            0 :         value.bits()
     127            0 :     }
     128              : }
     129              : impl std::fmt::Display for Flags {
     130            0 :     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
     131            0 :         bitflags::parser::to_writer(self, f)
     132            0 :     }
     133              : }
     134              : 
     135              : impl Section<'_> {
     136              :     /// Name of the segment that owns this section
     137       212280 :     pub fn segment_name(&self) -> String {
     138       212280 :         self.ptr.segment_name().to_string()
     139       212280 :     }
     140              : 
     141              :     /// Virtual base address of this section
     142       212280 :     pub fn address(&self) -> u64 {
     143       212280 :         self.ptr.address()
     144       212280 :     }
     145              : 
     146              :     /// Section alignment as a power of 2
     147       212280 :     pub fn alignment(&self) -> u32 {
     148       212280 :         self.ptr.alignment()
     149       212280 :     }
     150              : 
     151              : 
     152              :     /// Offset of the relocation table. This value should be 0
     153              :     /// for executable and libraries as the relocations are managed by
     154              :     /// [`crate::macho::Relocation::Dyld`] or [`crate::macho::Relocation::Fixup`]
     155              :     ///
     156              :     /// On the other hand, for object files (`.o`) this value should not be 0 (c.f. [`crate::macho::Relocation::Object`])
     157       212280 :     pub fn relocation_offset(&self) -> u32 {
     158       212280 :         self.ptr.relocation_offset()
     159       212280 :     }
     160              : 
     161              :     /// Number of relocations associated with this section
     162       212280 :     pub fn numberof_relocations(&self) -> u32 {
     163       212280 :         self.ptr.numberof_relocations()
     164       212280 :     }
     165              : 
     166       212280 :     pub fn raw_flags(&self) -> u32 {
     167       212280 :         self.ptr.raw_flags()
     168       212280 :     }
     169              : 
     170              :     /// Section's flags masked with `SECTION_FLAGS_MASK`
     171       212280 :     pub fn flags(&self) -> Flags {
     172       212280 :         Flags::from_bits_truncate(self.ptr.flags())
     173       212280 :     }
     174              : 
     175              :     /// Type of the section. This value can help to determine the purpose of the section
     176       212280 :     pub fn section_type(&self) -> Type {
     177       212280 :         Type::from(self.ptr.section_type())
     178       212280 :     }
     179              : 
     180              :     /// According to the official `loader.h` file, this value is reserved
     181              :     /// for *offset* or *index*
     182       212280 :     pub fn reserved1(&self) -> u32 {
     183       212280 :         self.ptr.reserved1()
     184       212280 :     }
     185              : 
     186              :     /// According to the official `loader.h` file, this value is reserved
     187              :     /// for *count* or *sizeof*
     188       212280 :     pub fn reserved2(&self) -> u32 {
     189       212280 :         self.ptr.reserved2()
     190       212280 :     }
     191              : 
     192              :     /// This value is only present for 64 bits Mach-O files. In that case,
     193              :     /// the value is *reserved*.
     194       212280 :     pub fn reserved3(&self) -> u32 {
     195       212280 :         self.ptr.reserved3()
     196       212280 :     }
     197              : 
     198              :     /// Segment bound to this section
     199         2310 :     pub fn segment(&self) -> Option<Segment> {
     200         2310 :         into_optional(self.ptr.segment())
     201         2310 :     }
     202              : 
     203              :     /// Iterator over the [`crate::macho::Relocation`] associated with thi section
     204         2310 :     pub fn relocations(&self) -> Relocations {
     205         2310 :         Relocations::new(self.ptr.relocations())
     206         2310 :     }
     207              : }
     208              : 
     209              : impl fmt::Debug for Section<'_> {
     210       212280 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     211       212280 :         let base = self as &dyn generic::Section;
     212       212280 :         f.debug_struct("Section")
     213       212280 :             .field("base", &base)
     214       212280 :             .field("segment_name", &self.segment_name())
     215       212280 :             .field("address", &self.address())
     216       212280 :             .field("alignment", &self.alignment())
     217       212280 :             .field("relocation_offset", &self.relocation_offset())
     218       212280 :             .field("numberof_relocations", &self.numberof_relocations())
     219       212280 :             .field("raw_flags", &self.raw_flags())
     220       212280 :             .field("flags", &self.flags())
     221       212280 :             .field("type", &self.section_type())
     222       212280 :             .field("reserved1", &self.reserved1())
     223       212280 :             .field("reserved2", &self.reserved2())
     224       212280 :             .field("reserved3", &self.reserved3())
     225       212280 :             .finish()
     226       212280 :     }
     227              : }
     228              : 
     229              : impl<'a> FromFFI<ffi::MachO_Section> for Section<'a> {
     230       212280 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::MachO_Section>) -> Self {
     231       212280 :         Self {
     232       212280 :             ptr,
     233       212280 :             _owner: PhantomData,
     234       212280 :         }
     235       212280 :     }
     236              : }
     237              : 
     238              : impl generic::Section for Section<'_> {
     239       849120 :     fn as_generic(&self) -> &ffi::AbstractSection {
     240       849120 :         self.ptr.as_ref().unwrap().as_ref()
     241       849120 :     }
     242              : }
     243              : 
     244         2310 : declare_iterator!(
     245         2310 :     Sections,
     246         2310 :     Section<'a>,
     247         2310 :     ffi::MachO_Section,
     248         2310 :     ffi::MachO_Binary,
     249         2310 :     ffi::MachO_Binary_it_sections
     250         2310 : );
     251        11520 : declare_iterator!(
     252        11520 :     Relocations,
     253        11520 :     Relocation<'a>,
     254        11520 :     ffi::MachO_Relocation,
     255        11520 :     ffi::MachO_Section,
     256        11520 :     ffi::MachO_Section_it_relocations
     257        11520 : );
        

Generated by: LCOV version 2.1-1