LCOV - code coverage report
Current view: top level - src/elf - header.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 79.6 % 137 109
Test Date: 2024-10-27:00:00:00 Functions: 53.7 % 54 29

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : 
       3              : use std::{fmt, marker::PhantomData};
       4              : 
       5              : use crate::common::FromFFI;
       6              : 
       7              : 
       8              : #[allow(non_camel_case_types)]
       9           64 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
      10              : /// The type of the underlying ELF file. This enum matches
      11              : /// the semantic of `ET_NONE`, `ET_REL`, ...
      12              : pub enum FileType {
      13              :     /// Can't be determined
      14              :     NONE,
      15              : 
      16              :     /// Relocatable file (or object file)
      17              :     REL,
      18              : 
      19              :     /// non-pie executable
      20              :     EXEC,
      21              : 
      22              :     /// Shared library **or** a pie-executable
      23              :     DYN,
      24              : 
      25              :     /// Core dump file
      26              :     CORE,
      27              :     UNKNOWN(u32),
      28              : }
      29              : 
      30              : 
      31              : impl FileType {
      32           64 :     pub fn from_value(value: u32) -> Self {
      33           64 :         match value {
      34            0 :             0x00000000 => FileType::NONE,
      35           16 :             0x00000001 => FileType::REL,
      36           24 :             0x00000002 => FileType::EXEC,
      37           16 :             0x00000003 => FileType::DYN,
      38            8 :             0x00000004 => FileType::CORE,
      39            0 :             _ => FileType::UNKNOWN(value),
      40              : 
      41              :         }
      42           64 :     }
      43              : }
      44              : 
      45              : 
      46              : #[allow(non_camel_case_types)]
      47          128 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
      48              : /// Match the result of `Elfxx_Ehdr.e_version`
      49              : pub enum Version {
      50              :     /// Invalid ELF version
      51              :     NONE,
      52              : 
      53              :     /// Current version (default)
      54              :     CURRENT,
      55              :     UNKNOWN(u32),
      56              : }
      57              : 
      58              : impl Version {
      59          128 :     pub fn from_value(value: u32) -> Self {
      60          128 :         match value {
      61            0 :             0x00000000 => Version::NONE,
      62          128 :             0x00000001 => Version::CURRENT,
      63            0 :             _ => Version::UNKNOWN(value),
      64              : 
      65              :         }
      66          128 :     }
      67              : }
      68              : 
      69              : 
      70              : #[allow(non_camel_case_types)]
      71           64 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
      72              : /// Match the result of `Elfxx_Ehdr.e_ident[EI_CLASS]`
      73              : pub enum Class {
      74              :     /// Invalid class
      75              :     NONE,
      76              : 
      77              :     /// 32-bit objects
      78              :     ELF32,
      79              : 
      80              :     /// 64-bits objects
      81              :     ELF64,
      82              :     UNKNOWN(u32),
      83              : }
      84              : 
      85              : impl Class {
      86           64 :     pub fn from_value(value: u32) -> Self {
      87           64 :         match value {
      88            0 :             0x00000000 => Class::NONE,
      89            8 :             0x00000001 => Class::ELF32,
      90           56 :             0x00000002 => Class::ELF64,
      91            0 :             _ => Class::UNKNOWN(value),
      92              : 
      93              :         }
      94           64 :     }
      95              : }
      96              : 
      97              : 
      98              : #[allow(non_camel_case_types)]
      99           64 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     100              : /// Match the result `Elfxx_Ehdr.e_ident[EI_OSABI]`
     101              : pub enum OsAbi {
     102              :     /// UNIX System V ABI
     103              :     SYSTEMV,
     104              :     /// HP-UX operating system
     105              :     HPUX,
     106              :     /// NetBSD
     107              :     NETBSD,
     108              :     /// GNU/Linux
     109              :     GNU,
     110              :     /// Historical alias for ELFOSABI_GNU.
     111              :     LINUX,
     112              :     /// GNU/Hurd
     113              :     HURD,
     114              :     /// Solaris
     115              :     SOLARIS,
     116              :     /// AIX
     117              :     AIX,
     118              :     /// IRIX
     119              :     IRIX,
     120              :     /// FreeBSD
     121              :     FREEBSD,
     122              :     /// TRU64 UNIX
     123              :     TRU64,
     124              :     /// Novell Modesto
     125              :     MODESTO,
     126              :     /// OpenBSD
     127              :     OPENBSD,
     128              :     /// OpenVMS
     129              :     OPENVMS,
     130              :     /// Hewlett-Packard Non-Stop Kernel
     131              :     NSK,
     132              :     /// AROS
     133              :     AROS,
     134              :     /// FenixOS
     135              :     FENIXOS,
     136              :     /// Nuxi CloudABI
     137              :     CLOUDABI,
     138              :     /// Bare-metal TMS320C6000
     139              :     C6000_ELFABI,
     140              :     /// AMD HSA runtim
     141              :     AMDGPU_HSA,
     142              :     /// Linux TMS320C6000
     143              :     C6000_LINUX,
     144              :     /// ARM
     145              :     ARM,
     146              :     /// Standalone (embedded) applicatio
     147              :     STANDALONE,
     148              :     UNKNOWN(u32),
     149              : }
     150              : 
     151              : 
     152              : impl OsAbi {
     153           64 :     pub fn from_value(value: u32) -> Self {
     154           64 :         match value {
     155           56 :             0x00000000 => OsAbi::SYSTEMV,
     156            0 :             0x00000001 => OsAbi::HPUX,
     157            0 :             0x00000002 => OsAbi::NETBSD,
     158            8 :             0x00000003 => OsAbi::LINUX,
     159            0 :             0x00000004 => OsAbi::HURD,
     160            0 :             0x00000006 => OsAbi::SOLARIS,
     161            0 :             0x00000007 => OsAbi::AIX,
     162            0 :             0x00000008 => OsAbi::IRIX,
     163            0 :             0x00000009 => OsAbi::FREEBSD,
     164            0 :             0x0000000a => OsAbi::TRU64,
     165            0 :             0x0000000b => OsAbi::MODESTO,
     166            0 :             0x0000000c => OsAbi::OPENBSD,
     167            0 :             0x0000000d => OsAbi::OPENVMS,
     168            0 :             0x0000000e => OsAbi::NSK,
     169            0 :             0x0000000f => OsAbi::AROS,
     170            0 :             0x00000010 => OsAbi::FENIXOS,
     171            0 :             0x00000011 => OsAbi::CLOUDABI,
     172              :             /* 0x00000040 => OsAbi::C6000_ELFABI, */
     173            0 :             0x00000040 => OsAbi::AMDGPU_HSA,
     174            0 :             0x00000041 => OsAbi::C6000_LINUX,
     175            0 :             0x00000061 => OsAbi::ARM,
     176            0 :             0x000000ff => OsAbi::STANDALONE,
     177            0 :             _ => OsAbi::UNKNOWN(value),
     178              : 
     179              :         }
     180           64 :     }
     181              : }
     182              : 
     183              : 
     184              : #[allow(non_camel_case_types)]
     185           64 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     186              : /// Match the result `Elfxx_Ehdr.e_ident[EI_DATA]`
     187              : pub enum ElfData {
     188              :     /// Invalid data encodin
     189              :     NONE,
     190              :     /// 2's complement, little endian
     191              :     LSB,
     192              :     /// 2's complement, big endian
     193              :     MSB,
     194              :     UNKNOWN(u32),
     195              : }
     196              : 
     197              : impl ElfData {
     198           64 :     pub fn from_value(value: u32) -> Self {
     199           64 :         match value {
     200            0 :             0x00000000 => ElfData::NONE,
     201           56 :             0x00000001 => ElfData::LSB,
     202            8 :             0x00000002 => ElfData::MSB,
     203            0 :             _ => ElfData::UNKNOWN(value),
     204              : 
     205              :         }
     206           64 :     }
     207              : }
     208              : 
     209              : /// Class which represents the ELF's header. This class mirrors the raw
     210              : /// ELF `Elfxx_Ehdr` structure
     211              : pub struct Header<'a> {
     212              :     ptr: cxx::UniquePtr<ffi::ELF_Header>,
     213              :     _owner: PhantomData<&'a ffi::ELF_Binary>
     214              : }
     215              : 
     216              : impl FromFFI<ffi::ELF_Header> for Header<'_> {
     217           64 :     fn from_ffi(hdr: cxx::UniquePtr<ffi::ELF_Header>) -> Self {
     218           64 :         Self {
     219           64 :             ptr: hdr,
     220           64 :             _owner: PhantomData
     221           64 :         }
     222           64 :     }
     223              : }
     224              : 
     225              : impl Header<'_> {
     226              :     /// Executable entrypoint
     227           64 :     pub fn entrypoint(&self) -> u64 {
     228           64 :         self.ptr.entrypoint()
     229           64 :     }
     230              : 
     231              :     /// Define the object file type. (e.g. executable, library...)
     232           64 :     pub fn file_type(&self) -> FileType {
     233           64 :         FileType::from_value(self.ptr.file_type())
     234           64 :     }
     235              : 
     236              :     /// Version of the object file format
     237           64 :     pub fn object_file_version(&self) -> Version {
     238           64 :         Version::from_value(self.ptr.object_file_version())
     239           64 :     }
     240              : 
     241              :     /// Return the object's class. `ELF64` or `ELF32`
     242           64 :     pub fn identity_class(&self) -> Class {
     243           64 :         Class::from_value(self.ptr.identity_class())
     244           64 :     }
     245              : 
     246              :     /// Specify the data encoding
     247           64 :     pub fn identity_data(&self) -> ElfData {
     248           64 :         ElfData::from_value(self.ptr.identity_data())
     249           64 :     }
     250              : 
     251              :     /// See: [`Header::object_file_version`]
     252           64 :     pub fn identity_version(&self) -> Version {
     253           64 :         Version::from_value(self.ptr.identity_version())
     254           64 :     }
     255              : 
     256              :     /// Identifies the version of the ABI for which the object is prepared
     257           64 :     pub fn identity_os_abi(&self) -> OsAbi {
     258           64 :         OsAbi::from_value(self.ptr.identity_os_abi())
     259           64 :     }
     260              : 
     261              :     /// Target architecture
     262           64 :     pub fn machine_type(&self) -> u32 {
     263           64 :         self.ptr.machine_type()
     264           64 :     }
     265              : 
     266              :     /// Offset of the programs table (also known as segments table)
     267           64 :     pub fn program_headers_offset(&self) -> u64 {
     268           64 :         self.ptr.program_headers_offset()
     269           64 :     }
     270              : 
     271              :     /// Offset of the sections table
     272           64 :     pub fn section_headers_offset(&self) -> u64 {
     273           64 :         self.ptr.section_headers_offset()
     274           64 :     }
     275              : 
     276              :     /// Processor-specific flags
     277           64 :     pub fn processor_flag(&self) -> u32 {
     278           64 :         self.ptr.processor_flag()
     279           64 :     }
     280              : 
     281              :     /// Size of the current header (i.e. `sizeof(Elfxx_Ehdr)`)
     282              :     /// This size should be 64 for an `ELF64` binary and 52 for an `ELF32`.
     283           64 :     pub fn header_size(&self) -> u32 {
     284           64 :         self.ptr.header_size()
     285           64 :     }
     286              : 
     287              :     /// Return the size of a program header (i.e. `sizeof(Elfxx_Phdr)`)
     288              :     /// This size should be 56 for an `ELF64` binary and 32 for an `ELF32`.
     289           64 :     pub fn program_header_size(&self) -> u32 {
     290           64 :         self.ptr.program_header_size()
     291           64 :     }
     292              : 
     293              :     /// Return the number of segments
     294           64 :     pub fn numberof_segments(&self) -> u32 {
     295           64 :         self.ptr.numberof_segments()
     296           64 :     }
     297              : 
     298              :     /// Return the size of a section header (i.e. `sizeof(Elfxx_Shdr)`)
     299              :     /// This size should be 64 for a ``ELF64`` binary and 40 for an ``ELF32``.
     300           64 :     pub fn section_header_size(&self) -> u32 {
     301           64 :         self.ptr.section_header_size()
     302           64 :     }
     303              : 
     304              :     /// Return the number of sections
     305              :     ///
     306              :     /// <div class="warning">
     307              :     /// This value could differ from the real number of sections
     308              :     /// present in the binary. It must be taken as an <i>indication</i>
     309              :     /// </div>
     310           64 :     pub fn numberof_sections(&self) -> u32 {
     311           64 :         self.ptr.numberof_sections()
     312           64 :     }
     313              : 
     314              :     /// Return the section's index which contains sections' names
     315           64 :     pub fn section_name_table_idx(&self) -> u32 {
     316           64 :         self.ptr.section_name_table_idx()
     317           64 :     }
     318              : }
     319              : 
     320              : impl fmt::Debug for Header<'_> {
     321           64 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     322           64 :         f.debug_struct("Header")
     323           64 :             .field("entrypoint", &self.entrypoint())
     324           64 :             .field("object_file_version", &self.object_file_version())
     325           64 :             .field("identity_class", &self.identity_class())
     326           64 :             .field("identity_os_abi", &self.identity_os_abi())
     327           64 :             .field("identity_data", &self.identity_data())
     328           64 :             .field("identity_version", &self.identity_version())
     329           64 :             .field("file_type", &self.file_type())
     330           64 :             .field("machine_type", &self.machine_type())
     331           64 :             .field("program_headers_offset", &self.program_headers_offset())
     332           64 :             .field("section_headers_offset", &self.section_headers_offset())
     333           64 :             .field("processor_flag", &self.processor_flag())
     334           64 :             .field("header_size", &self.header_size())
     335           64 :             .field("program_header_size", &self.program_header_size())
     336           64 :             .field("numberof_segments", &self.numberof_segments())
     337           64 :             .field("section_header_size", &self.section_header_size())
     338           64 :             .field("numberof_sections", &self.numberof_sections())
     339           64 :             .field("section_name_table_idx", &self.section_name_table_idx())
     340           64 :             .finish()
     341           64 :     }
     342              : }
        

Generated by: LCOV version 2.1-1