LCOV - code coverage report
Current view: top level - src/elf - section.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 45.9 % 196 90
Test Date: 2026-04-12:00:00:00 Functions: 54.5 % 33 18

            Line data    Source code
       1              : use bitflags::bitflags;
       2              : use lief_ffi as ffi;
       3              : use std::fmt;
       4              : use std::marker::PhantomData;
       5              : use std::pin::Pin;
       6              : 
       7              : use crate::common::FromFFI;
       8              : use crate::declare_iterator;
       9              : use crate::generic;
      10              : use crate::to_slice;
      11              : 
      12              : /// Structure which represents an ELF Section
      13              : pub struct Section<'a> {
      14              :     ptr: cxx::UniquePtr<ffi::ELF_Section>,
      15              :     _owner: PhantomData<&'a ()>,
      16              : }
      17              : 
      18              : impl Section<'_> {
      19              :     /// Type of the section
      20        14170 :     pub fn get_type(&self) -> Type {
      21        14170 :         Type::from(self.ptr.get_type())
      22        14170 :     }
      23              : 
      24              :     /// Sections flags
      25        14170 :     pub fn flags(&self) -> Flags {
      26        14170 :         Flags::from_value(self.ptr.flags())
      27        14170 :     }
      28              : 
      29              :     /// Section alignment
      30        14170 :     pub fn alignment(&self) -> u64 {
      31        14170 :         self.ptr.alignment()
      32        14170 :     }
      33              : 
      34              :     /// Section information.
      35              :     /// This meaning of this value depends on the section's type
      36        14170 :     pub fn information(&self) -> u64 {
      37        14170 :         self.ptr.information()
      38        14170 :     }
      39              : 
      40              :     /// This function returns the size of an element in the case of a section that contains
      41              :     /// an array.
      42              :     ///
      43              :     /// For instance, the `.dynamic` section contains an array of DynamicEntry. As the
      44              :     /// size of the raw C structure of this entry is 0x10 (`sizeof(Elf64_Dyn)`)
      45              :     /// in an ELF64, the `entry_size` is set to this value.
      46        14170 :     pub fn entry_size(&self) -> u64 {
      47        14170 :         self.ptr.entry_size()
      48        14170 :     }
      49              : 
      50              :     /// Index to another section
      51        14170 :     pub fn link(&self) -> u64 {
      52        14170 :         self.ptr.link()
      53        14170 :     }
      54              : 
      55              :     /// Offset in the file where the content of this section is located
      56        14170 :     pub fn file_offset(&self) -> u64 {
      57        14170 :         self.ptr.file_offset()
      58        14170 :     }
      59              : 
      60              :     /// Original size of the section (regardless modifications)
      61        14170 :     pub fn original_size(&self) -> u64 {
      62        14170 :         self.ptr.original_size()
      63        14170 :     }
      64              : 
      65              :     /// Content of the section as a slice of bytes
      66         3315 :     pub fn content(&self) -> &[u8] {
      67         3315 :         to_slice!(self.ptr.content());
      68         3315 :     }
      69              : }
      70              : 
      71              : #[allow(non_camel_case_types)]
      72        14170 : #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
      73              : pub enum Type {
      74              :     /// No associated section (inactive entry)
      75              :     SHT_NULL,
      76              :     /// Program-defined contents.
      77              :     PROGBITS,
      78              :     /// Symbol table
      79              :     SYMTAB,
      80              :     /// String table
      81              :     STRTAB,
      82              :     /// Relocation entries; explicit addends.
      83              :     RELA,
      84              :     /// Symbol hash table.
      85              :     HASH,
      86              :     /// Information for dynamic linking.
      87              :     DYNAMIC,
      88              :     /// Information about the file.
      89              :     NOTE,
      90              :     /// Data occupies no space in the file.
      91              :     NOBITS,
      92              :     /// Relocation entries; no explicit addends.
      93              :     REL,
      94              :     /// Reserved
      95              :     SHLIB,
      96              :     /// Symbol table.
      97              :     DYNSYM,
      98              :     /// Pointers to initialization functions.
      99              :     INIT_ARRAY,
     100              :     /// Pointers to termination functions.
     101              :     FINI_ARRAY,
     102              :     /// Pointers to pre-init functions.
     103              :     PREINIT_ARRAY,
     104              :     /// Section group.
     105              :     GROUP,
     106              :     /// Indices for SHN_XINDEX entries.
     107              :     SYMTAB_SHNDX,
     108              :     /// Relocation entries; only offsets.
     109              :     RELR,
     110              :     /// Packed relocations (Android specific).
     111              :     ANDROID_REL,
     112              :     /// Packed relocations (Android specific).
     113              :     ANDROID_RELA,
     114              :     /// This section is used to mark symbols as address-significant.
     115              :     LLVM_ADDRSIG,
     116              :     /// New relr relocations (Android specific).
     117              :     ANDROID_RELR,
     118              :     /// Object attributes.
     119              :     GNU_ATTRIBUTES,
     120              :     /// GNU-style hash table.
     121              :     GNU_HASH,
     122              :     /// GNU version definitions.
     123              :     GNU_VERDEF,
     124              :     /// GNU version references.
     125              :     GNU_VERNEED,
     126              :     /// GNU symbol versions table.
     127              :     GNU_VERSYM,
     128              :     /// Exception Index table
     129              :     ARM_EXIDX,
     130              :     /// BPABI DLL dynamic linking pre-emption map
     131              :     ARM_PREEMPTMAP,
     132              :     /// Object file compatibility attributes
     133              :     ARM_ATTRIBUTES,
     134              :     ARM_DEBUGOVERLAY,
     135              :     ARM_OVERLAYSECTION,
     136              :     /// Link editor is to sort the entries in this section based on their sizes
     137              :     HEX_ORDERED,
     138              :     /// Unwind information
     139              :     X86_64_UNWIND,
     140              :     /// Register usage information
     141              :     MIPS_REGINFO,
     142              :     /// General options
     143              :     MIPS_OPTIONS,
     144              :     /// ABI information
     145              :     MIPS_ABIFLAGS,
     146              :     /// RISC-V Attribute
     147              :     RISCV_ATTRIBUTES,
     148              :     UNKNOWN(u64),
     149              : }
     150              : 
     151              : impl From<u64> for Type {
     152        14170 :     fn from(value: u64) -> Self {
     153        14170 :         match value {
     154          117 :             0x00000000 => Type::SHT_NULL,
     155        10387 :             0x00000001 => Type::PROGBITS,
     156         1235 :             0x00000002 => Type::SYMTAB,
     157          260 :             0x00000003 => Type::STRTAB,
     158          195 :             0x00000004 => Type::RELA,
     159           26 :             0x00000005 => Type::HASH,
     160          104 :             0x00000006 => Type::DYNAMIC,
     161          234 :             0x00000007 => Type::NOTE,
     162          884 :             0x00000008 => Type::NOBITS,
     163           26 :             0x00000009 => Type::REL,
     164            0 :             0x0000000a => Type::SHLIB,
     165           91 :             0x0000000b => Type::DYNSYM,
     166          143 :             0x0000000e => Type::INIT_ARRAY,
     167           78 :             0x0000000f => Type::FINI_ARRAY,
     168            0 :             0x00000010 => Type::PREINIT_ARRAY,
     169           65 :             0x00000011 => Type::GROUP,
     170            0 :             0x00000012 => Type::SYMTAB_SHNDX,
     171            0 :             0x00000013 => Type::RELR,
     172            0 :             0x60000001 => Type::ANDROID_REL,
     173            0 :             0x60000002 => Type::ANDROID_RELA,
     174            0 :             0x6fff4c03 => Type::LLVM_ADDRSIG,
     175            0 :             0x6fffff00 => Type::ANDROID_RELR,
     176           13 :             0x6ffffff5 => Type::GNU_ATTRIBUTES,
     177           78 :             0x6ffffff6 => Type::GNU_HASH,
     178           13 :             0x6ffffffd => Type::GNU_VERDEF,
     179           91 :             0x6ffffffe => Type::GNU_VERNEED,
     180           91 :             0x6fffffff => Type::GNU_VERSYM,
     181            0 :             0x170000001 => Type::ARM_EXIDX,
     182            0 :             0x170000002 => Type::ARM_PREEMPTMAP,
     183            0 :             0x170000003 => Type::ARM_ATTRIBUTES,
     184            0 :             0x170000004 => Type::ARM_DEBUGOVERLAY,
     185            0 :             0x170000005 => Type::ARM_OVERLAYSECTION,
     186            0 :             0x270000000 => Type::HEX_ORDERED,
     187            0 :             0x270000001 => Type::X86_64_UNWIND,
     188           13 :             0x370000006 => Type::MIPS_REGINFO,
     189            0 :             0x37000000d => Type::MIPS_OPTIONS,
     190           13 :             0x37000002a => Type::MIPS_ABIFLAGS,
     191            0 :             0x470000003 => Type::RISCV_ATTRIBUTES,
     192           13 :             _ => Type::UNKNOWN(value),
     193              :         }
     194        14170 :     }
     195              : }
     196              : impl From<Type> for u64 {
     197            0 :     fn from(value: Type) -> u64 {
     198            0 :         match value {
     199            0 :             Type::SHT_NULL => 0x00000000,
     200            0 :             Type::PROGBITS => 0x00000001,
     201            0 :             Type::SYMTAB => 0x00000002,
     202            0 :             Type::STRTAB => 0x00000003,
     203            0 :             Type::RELA => 0x00000004,
     204            0 :             Type::HASH => 0x00000005,
     205            0 :             Type::DYNAMIC => 0x00000006,
     206            0 :             Type::NOTE => 0x00000007,
     207            0 :             Type::NOBITS => 0x00000008,
     208            0 :             Type::REL => 0x00000009,
     209            0 :             Type::SHLIB => 0x0000000a,
     210            0 :             Type::DYNSYM => 0x0000000b,
     211            0 :             Type::INIT_ARRAY => 0x0000000e,
     212            0 :             Type::FINI_ARRAY => 0x0000000f,
     213            0 :             Type::PREINIT_ARRAY => 0x00000010,
     214            0 :             Type::GROUP => 0x00000011,
     215            0 :             Type::SYMTAB_SHNDX => 0x00000012,
     216            0 :             Type::RELR => 0x00000013,
     217            0 :             Type::ANDROID_REL => 0x60000001,
     218            0 :             Type::ANDROID_RELA => 0x60000002,
     219            0 :             Type::LLVM_ADDRSIG => 0x6fff4c03,
     220            0 :             Type::ANDROID_RELR => 0x6fffff00,
     221            0 :             Type::GNU_ATTRIBUTES => 0x6ffffff5,
     222            0 :             Type::GNU_HASH => 0x6ffffff6,
     223            0 :             Type::GNU_VERDEF => 0x6ffffffd,
     224            0 :             Type::GNU_VERNEED => 0x6ffffffe,
     225            0 :             Type::GNU_VERSYM => 0x6fffffff,
     226            0 :             Type::ARM_EXIDX => 0x170000001,
     227            0 :             Type::ARM_PREEMPTMAP => 0x170000002,
     228            0 :             Type::ARM_ATTRIBUTES => 0x170000003,
     229            0 :             Type::ARM_DEBUGOVERLAY => 0x170000004,
     230            0 :             Type::ARM_OVERLAYSECTION => 0x170000005,
     231            0 :             Type::HEX_ORDERED => 0x270000000,
     232            0 :             Type::X86_64_UNWIND => 0x270000001,
     233            0 :             Type::MIPS_REGINFO => 0x370000006,
     234            0 :             Type::MIPS_OPTIONS => 0x37000000d,
     235            0 :             Type::MIPS_ABIFLAGS => 0x37000002a,
     236            0 :             Type::RISCV_ATTRIBUTES => 0x470000003,
     237            0 :             Type::UNKNOWN(value) => value,
     238              :         }
     239            0 :     }
     240              : }
     241              : 
     242            0 : bitflags! {
     243        14170 :     #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
     244            0 :     pub struct Flags: u64 {
     245            0 :         const NONE = 0x0;
     246            0 :         const WRITE = 0x1;
     247            0 :         const ALLOC = 0x2;
     248            0 :         const EXECINSTR = 0x4;
     249            0 :         const MERGE = 0x10;
     250            0 :         const STRINGS = 0x20;
     251            0 :         const INFO_LINK = 0x40;
     252            0 :         const LINK_ORDER = 0x80;
     253            0 :         const OS_NONCONFORMING = 0x100;
     254            0 :         const GROUP = 0x200;
     255            0 :         const TLS = 0x400;
     256            0 :         const COMPRESSED = 0x800;
     257            0 :         const GNU_RETAIN = 0x200000;
     258            0 :         const EXCLUDE = 0x80000000;
     259            0 :         const XCORE_SHF_DP_SECTION = 0x110000000;
     260            0 :         const XCORE_SHF_CP_SECTION = 0x120000000;
     261            0 :         const X86_64_LARGE = 0x210000000;
     262            0 :         const HEX_GPREL = 0x310000000;
     263            0 :         const MIPS_NODUPES = 0x401000000;
     264            0 :         const MIPS_NAMES = 0x402000000;
     265            0 :         const MIPS_LOCAL = 0x404000000;
     266            0 :         const MIPS_NOSTRIP = 0x408000000;
     267            0 :         const MIPS_GPREL = 0x410000000;
     268            0 :         const MIPS_MERGE = 0x420000000;
     269            0 :         const MIPS_ADDR = 0x440000000;
     270            0 :         const MIPS_STRING = 0x480000000;
     271            0 :         const ARM_PURECODE = 0x520000000;
     272            0 :     }
     273            0 : }
     274              : 
     275              : impl Flags {
     276        14170 :     pub fn from_value(value: u64) -> Self {
     277        14170 :         Flags::from_bits_truncate(value)
     278        14170 :     }
     279              : }
     280              : 
     281              : impl fmt::Debug for Section<'_> {
     282        14170 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     283        14170 :         let base = self as &dyn generic::Section;
     284        14170 :         f.debug_struct("Section")
     285        14170 :             .field("base", &base)
     286        14170 :             .field("type", &self.get_type())
     287        14170 :             .field("flags", &self.flags())
     288        14170 :             .field("alignment", &self.alignment())
     289        14170 :             .field("information", &self.information())
     290        14170 :             .field("entry_size", &self.entry_size())
     291        14170 :             .field("link", &self.link())
     292        14170 :             .field("file_offset", &self.file_offset())
     293        14170 :             .field("original_size", &self.original_size())
     294        14170 :             .finish()
     295        14170 :     }
     296              : }
     297              : 
     298              : impl fmt::Display for Section<'_> {
     299         3211 :     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     300         3211 :         write!(f, "{}", self.ptr.to_string())
     301         3211 :     }
     302              : }
     303              : 
     304              : impl FromFFI<ffi::ELF_Section> for Section<'_> {
     305        14196 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_Section>) -> Self {
     306        14196 :         Self {
     307        14196 :             ptr,
     308        14196 :             _owner: PhantomData,
     309        14196 :         }
     310        14196 :     }
     311              : }
     312              : 
     313              : impl crate::common::AsFFI<ffi::ELF_Section> for Section<'_> {
     314            0 :     fn as_ffi(&self) -> &ffi::ELF_Section {
     315            0 :         self.ptr.as_ref().unwrap()
     316            0 :     }
     317              : 
     318            0 :     fn as_mut_ffi(&mut self) -> Pin<&mut ffi::ELF_Section> {
     319            0 :         self.ptr.pin_mut()
     320            0 :     }
     321              : }
     322              : 
     323              : impl generic::Section for Section<'_> {
     324        72852 :     fn as_generic(&self) -> &ffi::AbstractSection {
     325        72852 :         self.ptr.as_ref().unwrap().as_ref()
     326        72852 :     }
     327              : 
     328            0 :     fn as_generic_mut(&mut self) -> Pin<&mut ffi::AbstractSection> {
     329            0 :         unsafe {
     330            0 :             Pin::new_unchecked({
     331            0 :                 (self.ptr.as_ref().unwrap().as_ref() as *const ffi::AbstractSection
     332            0 :                     as *mut ffi::AbstractSection)
     333            0 :                     .as_mut()
     334            0 :                     .unwrap()
     335            0 :             })
     336            0 :         }
     337            0 :     }
     338              : }
     339              : 
     340         3211 : declare_iterator!(
     341         3211 :     Sections,
     342         3211 :     Section<'a>,
     343         3211 :     ffi::ELF_Section,
     344         3211 :     ffi::ELF_Binary,
     345         3211 :     ffi::ELF_Binary_it_sections
     346         3211 : );
        

Generated by: LCOV version 2.1-1