LCOV - code coverage report
Current view: top level - src/elf - section.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 48.6 % 175 85
Test Date: 2024-10-27:00:00:00 Functions: 60.0 % 30 18

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

Generated by: LCOV version 2.1-1