LCOV - code coverage report
Current view: top level - src/elf - segment.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 62.9 % 105 66
Test Date: 2025-02-23:00:00:00 Functions: 61.5 % 26 16

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : use bitflags::bitflags;
       3              : use std::fmt;
       4              : use std::marker::PhantomData;
       5              : 
       6              : use crate::common::FromFFI;
       7              : use crate::{declare_iterator, to_slice};
       8              : 
       9              : #[allow(non_camel_case_types)]
      10          690 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
      11              : pub enum Type {
      12              :     /// Unused segment
      13              :     PT_NULL,
      14              :     /// Loadable segment
      15              :     LOAD,
      16              :     /// Dynamic linking information.
      17              :     DYNAMIC,
      18              :     /// Interpreter pathname.
      19              :     INTERP,
      20              :     /// Auxiliary information.
      21              :     NOTE,
      22              :     /// Reserved
      23              :     SHLIB,
      24              :     /// The program header table itself.
      25              :     PHDR,
      26              :     /// The thread-local storage template.
      27              :     TLS,
      28              :     GNU_EH_FRAME,
      29              :     /// Indicates stack executability
      30              :     GNU_STACK,
      31              :     /// GNU property
      32              :     GNU_PROPERTY,
      33              :     /// Read-only after relocation.
      34              :     GNU_RELRO,
      35              :     PAX_FLAGS,
      36              :     /// Platform architecture compatibility info
      37              :     ARM_ARCHEXT,
      38              :     ARM_EXIDX,
      39              :     ARM_UNWIND,
      40              :     AARCH64_MEMTAG_MTE,
      41              :     /// Register usage information
      42              :     MIPS_REGINFO,
      43              :     /// Runtime procedure table.
      44              :     MIPS_RTPROC,
      45              :     /// Options segment.
      46              :     MIPS_OPTIONS,
      47              :     /// Abiflags segment.
      48              :     MIPS_ABIFLAGS,
      49              :     RISCV_ATTRIBUTES,
      50              :     IA_64_EXT,
      51              :     IA_64_UNWIND,
      52              :     HP_TLS,
      53              :     HP_CORE_NONE,
      54              :     HP_CORE_VERSION,
      55              :     HP_CORE_KERNEL,
      56              :     HP_CORE_COMM,
      57              :     HP_CORE_PROC,
      58              :     HP_CORE_LOADABLE,
      59              :     HP_CORE_STACK,
      60              :     HP_CORE_SHM,
      61              :     HP_CORE_MMF,
      62              :     HP_PARALLEL,
      63              :     HP_FASTBIND,
      64              :     HP_OPT_ANNOT,
      65              :     HP_HSL_ANNOT,
      66              :     HP_STACK,
      67              :     HP_CORE_UTSNAME,
      68              :     UNKNOWN(u64),
      69              : }
      70              : 
      71              : impl Type {
      72         1380 :     pub fn from_value(value: u64) -> Self {
      73         1380 :         match value {
      74           20 :             0x00000000 => Type::PT_NULL,
      75          600 :             0x00000001 => Type::LOAD,
      76          100 :             0x00000002 => Type::DYNAMIC,
      77           80 :             0x00000003 => Type::INTERP,
      78          140 :             0x00000004 => Type::NOTE,
      79            0 :             0x00000005 => Type::SHLIB,
      80           80 :             0x00000006 => Type::PHDR,
      81           20 :             0x00000007 => Type::TLS,
      82          100 :             0x6474e550 => Type::GNU_EH_FRAME,
      83          100 :             0x6474e551 => Type::GNU_STACK,
      84           20 :             0x6474e553 => Type::GNU_PROPERTY,
      85           80 :             0x6474e552 => Type::GNU_RELRO,
      86            0 :             0x65041580 => Type::PAX_FLAGS,
      87            0 :             0x270000000 => Type::ARM_ARCHEXT,
      88            0 :             0x270000001 => Type::ARM_EXIDX,
      89            0 :             0x470000002 => Type::AARCH64_MEMTAG_MTE,
      90           20 :             0x670000000 => Type::MIPS_REGINFO,
      91            0 :             0x670000001 => Type::MIPS_RTPROC,
      92            0 :             0x670000002 => Type::MIPS_OPTIONS,
      93           20 :             0x670000003 => Type::MIPS_ABIFLAGS,
      94            0 :             0x870000003 => Type::RISCV_ATTRIBUTES,
      95            0 :             0xa70000000 => Type::IA_64_EXT,
      96            0 :             0xa70000001 => Type::IA_64_UNWIND,
      97            0 :             0x20000060000000 => Type::HP_TLS,
      98            0 :             0x20000060000001 => Type::HP_CORE_NONE,
      99            0 :             0x20000060000002 => Type::HP_CORE_VERSION,
     100            0 :             0x20000060000003 => Type::HP_CORE_KERNEL,
     101            0 :             0x20000060000004 => Type::HP_CORE_COMM,
     102            0 :             0x20000060000005 => Type::HP_CORE_PROC,
     103            0 :             0x20000060000006 => Type::HP_CORE_LOADABLE,
     104            0 :             0x20000060000007 => Type::HP_CORE_STACK,
     105            0 :             0x20000060000008 => Type::HP_CORE_SHM,
     106            0 :             0x20000060000009 => Type::HP_CORE_MMF,
     107            0 :             0x20000060000010 => Type::HP_PARALLEL,
     108            0 :             0x20000060000011 => Type::HP_FASTBIND,
     109            0 :             0x20000060000012 => Type::HP_OPT_ANNOT,
     110            0 :             0x20000060000013 => Type::HP_HSL_ANNOT,
     111            0 :             0x20000060000014 => Type::HP_STACK,
     112            0 :             0x20000060000015 => Type::HP_CORE_UTSNAME,
     113            0 :             _ => Type::UNKNOWN(value),
     114              : 
     115              :         }
     116         1380 :     }
     117              : }
     118              : 
     119              : 
     120              : 
     121            0 : bitflags! {
     122            0 :     #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     123            0 :     pub struct Flags: u32 {
     124            0 :         const NONE = 0x0;
     125            0 :         const X = 0x1;
     126            0 :         const W = 0x2;
     127            0 :         const R = 0x4;
     128            0 :     }
     129            0 : }
     130              : 
     131              : 
     132              : impl Flags {
     133            0 :     pub fn from_value(value: u32) -> Self {
     134            0 :         Flags::from_bits_truncate(value)
     135            0 :     }
     136              : }
     137              : 
     138              : /// Structure which reprents an ELF segment
     139              : pub struct Segment<'a> {
     140              :     ptr: cxx::UniquePtr<ffi::ELF_Segment>,
     141              :     _owner: PhantomData<&'a ffi::ELF_Binary>
     142              : }
     143              : 
     144              : impl fmt::Debug for Segment<'_> {
     145          690 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     146          690 :         f.debug_struct("Segment")
     147          690 :             .field("p_type", &self.p_type())
     148          690 :             .field("flags", &self.flags())
     149          690 :             .field("file_offset", &self.file_offset())
     150          690 :             .field("virtual_address", &self.virtual_address())
     151          690 :             .field("physical_address", &self.physical_address())
     152          690 :             .field("physical_size", &self.physical_size())
     153          690 :             .field("virtual_size", &self.virtual_size())
     154          690 :             .field("alignment", &self.alignment())
     155          690 :             .finish()
     156          690 :     }
     157              : }
     158              : 
     159              : impl FromFFI<ffi::ELF_Segment> for Segment<'_> {
     160          710 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_Segment>) -> Self {
     161          710 :         Segment {
     162          710 :             ptr,
     163          710 :             _owner: PhantomData
     164          710 :         }
     165          710 :     }
     166              : }
     167              : 
     168              : impl<'a> Segment<'a> {
     169              :     /// Content of the segment as a slice of bytes
     170           40 :     pub fn content(&self) -> &[u8] {
     171           40 :         to_slice!(self.ptr.content());
     172           40 :     }
     173              : 
     174              :     /// The segment's type (LOAD, DYNAMIC, ...)
     175         1380 :     pub fn p_type(&self) -> Type {
     176         1380 :         Type::from_value(self.ptr.stype())
     177         1380 :     }
     178              : 
     179              :     /// The flag permissions associated with this segment
     180          690 :     pub fn flags(&self) -> u32 {
     181          690 :         self.ptr.flags()
     182          690 :     }
     183              : 
     184              :     /// The file offset of the data associated with this segment
     185          690 :     pub fn file_offset(&self) -> u64 {
     186          690 :         self.ptr.file_offset()
     187          690 :     }
     188              : 
     189              :     /// The virtual address of the segment.
     190          690 :     pub fn virtual_address(&self) -> u64 {
     191          690 :         self.ptr.virtual_address()
     192          690 :     }
     193              :     /// The physical address of the segment.
     194              :     /// This value is not really relevant on systems like Linux or Android.
     195              :     /// On the other hand, Qualcomm trustlets might use this value.
     196              :     ///
     197              :     /// Usually this value matches [`Segment::virtual_address`]
     198          690 :     pub fn physical_address(&self) -> u64 {
     199          690 :         self.ptr.physical_address()
     200          690 :     }
     201              : 
     202              :     /// The **file** size of the data associated with this segment
     203          690 :     pub fn physical_size(&self) -> u64 {
     204          690 :         self.ptr.physical_size()
     205          690 :     }
     206              : 
     207              :     /// The in-memory size of this segment.
     208              :     /// Usually, if the `.bss` segment is wrapped by this segment
     209              :     /// then, virtual_size is larger than physical_size
     210          690 :     pub fn virtual_size(&self) -> u64 {
     211          690 :         self.ptr.virtual_size()
     212          690 :     }
     213              : 
     214              :     /// The offset alignment of the segment
     215          690 :     pub fn alignment(&self) -> u64 {
     216          690 :         self.ptr.alignment()
     217          690 :     }
     218              : }
     219              : 
     220              : impl fmt::Display for Segment<'_> {
     221          690 :     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     222          690 :         write!(f, "{}", self.ptr.to_string())
     223          690 :     }
     224              : }
     225              : 
     226          690 : declare_iterator!(Segments, Segment<'a>, ffi::ELF_Segment, ffi::ELF_Binary, ffi::ELF_Binary_it_segments);
        

Generated by: LCOV version 2.1-1