LCOV - code coverage report
Current view: top level - src/elf/note/core - prstatus.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 31.3 % 166 52
Test Date: 2026-04-12:00:00:00 Functions: 36.4 % 33 12

            Line data    Source code
       1              : use lief_ffi as ffi;
       2              : use std::marker::PhantomData;
       3              : use std::time::Duration;
       4              : 
       5              : use crate::common::FromFFI;
       6              : use crate::elf::header::Arch;
       7              : use crate::elf::note::NoteBase;
       8              : use crate::{to_result, Error};
       9              : 
      10              : #[allow(non_camel_case_types)]
      11            0 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
      12              : /// Register for the x86 architecture
      13              : pub enum RegX86 {
      14              :     EBX,
      15              :     ECX,
      16              :     EDX,
      17              :     ESI,
      18              :     EDI,
      19              :     EBP,
      20              :     EAX,
      21              :     DS,
      22              :     ES,
      23              :     FS,
      24              :     GS,
      25              :     ORIG_EAX,
      26              :     EIP,
      27              :     CS,
      28              :     EFLAGS,
      29              :     ESP,
      30              :     SS,
      31              :     UNKNOWN(u32),
      32              : }
      33              : 
      34              : impl From<u32> for RegX86 {
      35            0 :     fn from(value: u32) -> Self {
      36            0 :         match value {
      37            0 :             0 => RegX86::EBX,
      38            0 :             1 => RegX86::ECX,
      39            0 :             2 => RegX86::EDX,
      40            0 :             3 => RegX86::ESI,
      41            0 :             4 => RegX86::EDI,
      42            0 :             5 => RegX86::EBP,
      43            0 :             6 => RegX86::EAX,
      44            0 :             7 => RegX86::DS,
      45            0 :             8 => RegX86::ES,
      46            0 :             9 => RegX86::FS,
      47            0 :             10 => RegX86::GS,
      48            0 :             11 => RegX86::ORIG_EAX,
      49            0 :             12 => RegX86::EIP,
      50            0 :             13 => RegX86::CS,
      51            0 :             14 => RegX86::EFLAGS,
      52            0 :             15 => RegX86::ESP,
      53            0 :             16 => RegX86::SS,
      54            0 :             _ => RegX86::UNKNOWN(value),
      55              :         }
      56            0 :     }
      57              : }
      58              : 
      59              : #[allow(non_camel_case_types)]
      60            0 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
      61              : /// Register for the x86-64 architecture
      62              : pub enum RegX86_64 {
      63              :     R15,
      64              :     R14,
      65              :     R13,
      66              :     R12,
      67              :     RBP,
      68              :     RBX,
      69              :     R11,
      70              :     R10,
      71              :     R9,
      72              :     R8,
      73              :     RAX,
      74              :     RCX,
      75              :     RDX,
      76              :     RSI,
      77              :     RDI,
      78              :     ORIG_RAX,
      79              :     RIP,
      80              :     CS,
      81              :     EFLAGS,
      82              :     RSP,
      83              :     SS,
      84              :     FS_BASE,
      85              :     GS_BASE,
      86              :     DS,
      87              :     ES,
      88              :     UNKNOWN(u32),
      89              : }
      90              : 
      91              : impl From<u32> for RegX86_64 {
      92            0 :     fn from(value: u32) -> Self {
      93            0 :         match value {
      94            0 :             0 => RegX86_64::R15,
      95            0 :             1 => RegX86_64::R14,
      96            0 :             2 => RegX86_64::R13,
      97            0 :             3 => RegX86_64::R12,
      98            0 :             4 => RegX86_64::RBP,
      99            0 :             5 => RegX86_64::RBX,
     100            0 :             6 => RegX86_64::R11,
     101            0 :             7 => RegX86_64::R10,
     102            0 :             8 => RegX86_64::R9,
     103            0 :             9 => RegX86_64::R8,
     104            0 :             10 => RegX86_64::RAX,
     105            0 :             11 => RegX86_64::RCX,
     106            0 :             12 => RegX86_64::RDX,
     107            0 :             13 => RegX86_64::RSI,
     108            0 :             14 => RegX86_64::RDI,
     109            0 :             15 => RegX86_64::ORIG_RAX,
     110            0 :             16 => RegX86_64::RIP,
     111            0 :             17 => RegX86_64::CS,
     112            0 :             18 => RegX86_64::EFLAGS,
     113            0 :             19 => RegX86_64::RSP,
     114            0 :             20 => RegX86_64::SS,
     115            0 :             21 => RegX86_64::FS_BASE,
     116            0 :             22 => RegX86_64::GS_BASE,
     117            0 :             23 => RegX86_64::DS,
     118            0 :             24 => RegX86_64::ES,
     119            0 :             _ => RegX86_64::UNKNOWN(value),
     120              :         }
     121            0 :     }
     122              : }
     123              : 
     124              : #[allow(non_camel_case_types)]
     125            0 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
     126              : /// Register for the ARM architecture
     127              : pub enum RegARM {
     128              :     R0,
     129              :     R1,
     130              :     R2,
     131              :     R3,
     132              :     R4,
     133              :     R5,
     134              :     R6,
     135              :     R7,
     136              :     R8,
     137              :     R9,
     138              :     R10,
     139              :     R11,
     140              :     R12,
     141              :     R13,
     142              :     R14,
     143              :     R15,
     144              :     CPSR,
     145              :     UNKNOWN(u32),
     146              : }
     147              : 
     148              : impl From<u32> for RegARM {
     149            0 :     fn from(value: u32) -> Self {
     150            0 :         match value {
     151            0 :             0 => RegARM::R0,
     152            0 :             1 => RegARM::R1,
     153            0 :             2 => RegARM::R2,
     154            0 :             3 => RegARM::R3,
     155            0 :             4 => RegARM::R4,
     156            0 :             5 => RegARM::R5,
     157            0 :             6 => RegARM::R6,
     158            0 :             7 => RegARM::R7,
     159            0 :             8 => RegARM::R8,
     160            0 :             9 => RegARM::R9,
     161            0 :             10 => RegARM::R10,
     162            0 :             11 => RegARM::R11,
     163            0 :             12 => RegARM::R12,
     164            0 :             13 => RegARM::R13,
     165            0 :             14 => RegARM::R14,
     166            0 :             15 => RegARM::R15,
     167            0 :             16 => RegARM::CPSR,
     168            0 :             _ => RegARM::UNKNOWN(value),
     169              :         }
     170            0 :     }
     171              : }
     172              : 
     173              : #[allow(non_camel_case_types)]
     174            0 : #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
     175              : /// Register for the AArch64 architecture
     176              : pub enum RegAArch64 {
     177              :     X0,
     178              :     X1,
     179              :     X2,
     180              :     X3,
     181              :     X4,
     182              :     X5,
     183              :     X6,
     184              :     X7,
     185              :     X8,
     186              :     X9,
     187              :     X10,
     188              :     X11,
     189              :     X12,
     190              :     X13,
     191              :     X14,
     192              :     X15,
     193              :     X16,
     194              :     X17,
     195              :     X18,
     196              :     X19,
     197              :     X20,
     198              :     X21,
     199              :     X22,
     200              :     X23,
     201              :     X24,
     202              :     X25,
     203              :     X26,
     204              :     X27,
     205              :     X28,
     206              :     X29,
     207              :     X30,
     208              :     X31,
     209              :     PC,
     210              :     PSTATE,
     211              :     UNKNOWN(u32),
     212              : }
     213              : 
     214              : impl From<u32> for RegAArch64 {
     215            0 :     fn from(value: u32) -> Self {
     216            0 :         match value {
     217            0 :             0 => RegAArch64::X0,
     218            0 :             1 => RegAArch64::X1,
     219            0 :             2 => RegAArch64::X2,
     220            0 :             3 => RegAArch64::X3,
     221            0 :             4 => RegAArch64::X4,
     222            0 :             5 => RegAArch64::X5,
     223            0 :             6 => RegAArch64::X6,
     224            0 :             7 => RegAArch64::X7,
     225            0 :             8 => RegAArch64::X8,
     226            0 :             9 => RegAArch64::X9,
     227            0 :             10 => RegAArch64::X10,
     228            0 :             11 => RegAArch64::X11,
     229            0 :             12 => RegAArch64::X12,
     230            0 :             13 => RegAArch64::X13,
     231            0 :             14 => RegAArch64::X14,
     232            0 :             15 => RegAArch64::X15,
     233            0 :             16 => RegAArch64::X16,
     234            0 :             17 => RegAArch64::X17,
     235            0 :             18 => RegAArch64::X18,
     236            0 :             19 => RegAArch64::X19,
     237            0 :             20 => RegAArch64::X20,
     238            0 :             21 => RegAArch64::X21,
     239            0 :             22 => RegAArch64::X22,
     240            0 :             23 => RegAArch64::X23,
     241            0 :             24 => RegAArch64::X24,
     242            0 :             25 => RegAArch64::X25,
     243            0 :             26 => RegAArch64::X26,
     244            0 :             27 => RegAArch64::X27,
     245            0 :             28 => RegAArch64::X28,
     246            0 :             29 => RegAArch64::X29,
     247            0 :             30 => RegAArch64::X30,
     248            0 :             31 => RegAArch64::X31,
     249            0 :             32 => RegAArch64::PC,
     250            0 :             33 => RegAArch64::PSTATE,
     251            0 :             _ => RegAArch64::UNKNOWN(value),
     252              :         }
     253            0 :     }
     254              : }
     255              : 
     256              : /// Status information from a core dump
     257              : ///
     258              : /// This structure mirrors the kernel's `prstatus` data embedded in
     259              : /// `NT_PRSTATUS` core-dump notes and exposes signal state, process
     260              : /// identifiers, and CPU-time accounting.
     261            0 : #[derive(Debug)]
     262              : pub struct Status {
     263              :     /// Current signal number being delivered
     264              :     pub cursig: u16,
     265              :     /// Set of pending signals (bitmask)
     266              :     pub sigpend: u64,
     267              :     /// Set of held (blocked) signals (bitmask)
     268              :     pub sighold: u64,
     269              :     /// Process ID
     270              :     pub pid: i32,
     271              :     /// Parent process ID
     272              :     pub ppid: i32,
     273              :     /// Process group ID
     274              :     pub pgrp: i32,
     275              :     /// Session ID
     276              :     pub sid: i32,
     277              :     /// Signal number that caused the core dump
     278              :     pub signo: i32,
     279              :     /// Signal code providing additional detail
     280              :     pub sigcode: i32,
     281              :     /// Error number associated with the signal
     282              :     pub sigerr: i32,
     283              : 
     284              :     /// Reserved field for alignment
     285              :     pub reserved: u16,
     286              : 
     287              :     /// User CPU time consumed by the process
     288              :     pub utime: Duration,
     289              :     /// System CPU time consumed by the process
     290              :     pub stime: Duration,
     291              :     /// User CPU time consumed by waited-for children
     292              :     pub cutime: Duration,
     293              :     /// System CPU time consumed by waited-for children
     294              :     pub cstime: Duration,
     295              : }
     296              : 
     297              : /// Note representing core process status (`NT_PRSTATUS`)
     298              : pub struct PrStatus<'a> {
     299              :     ptr: cxx::UniquePtr<ffi::ELF_CorePrStatus>,
     300              :     _owner: PhantomData<&'a ffi::ELF_Binary>,
     301              : }
     302              : 
     303              : impl PrStatus<'_> {
     304              :     /// The architecture
     305           26 :     pub fn architecture(&self) -> Arch {
     306           26 :         Arch::from(self.ptr.architecture())
     307           26 :     }
     308              : 
     309              :     /// Status information
     310           26 :     pub fn status(&self) -> Status {
     311           26 :         let status_ffi = self.ptr.status();
     312           26 :         Status {
     313           26 :             cursig: status_ffi.cursig,
     314           26 :             sigpend: status_ffi.sigpend,
     315           26 :             sighold: status_ffi.sighold,
     316           26 :             pid: status_ffi.pid,
     317           26 :             ppid: status_ffi.ppid,
     318           26 :             pgrp: status_ffi.pgrp,
     319           26 :             sid: status_ffi.sid,
     320           26 :             signo: status_ffi.signo,
     321           26 :             sigcode: status_ffi.code,
     322           26 :             sigerr: status_ffi.err,
     323           26 :             reserved: status_ffi.reserved,
     324           26 :             utime: Duration::new(status_ffi.utime_sec, status_ffi.utime_usec as u32),
     325           26 :             stime: Duration::new(status_ffi.stime_sec, status_ffi.stime_usec as u32),
     326           26 :             cutime: Duration::new(status_ffi.cutime_sec, status_ffi.cutime_usec as u32),
     327           26 :             cstime: Duration::new(status_ffi.cstime_sec, status_ffi.cstime_usec as u32),
     328           26 :         }
     329           26 :     }
     330              : 
     331              :     /// The program counter
     332           26 :     pub fn pc(&self) -> Result<u64, Error> {
     333           26 :         to_result!(ffi::ELF_CorePrStatus::pc, &self);
     334           26 :     }
     335              : 
     336              :     //// The stack pointer value
     337           13 :     pub fn sp(&self) -> Result<u64, Error> {
     338           13 :         to_result!(ffi::ELF_CorePrStatus::sp, &self);
     339           13 :     }
     340              : 
     341              :     /// The return value register
     342           13 :     pub fn return_value(&self) -> Result<u64, Error> {
     343           13 :         to_result!(ffi::ELF_CorePrStatus::return_value, &self);
     344           13 :     }
     345              : 
     346              :     /// Get all register values
     347           26 :     pub fn register_values(&self) -> Vec<u64> {
     348           26 :         Vec::from(self.ptr.register_values().as_slice())
     349           26 :     }
     350              : }
     351              : 
     352              : impl NoteBase for PrStatus<'_> {
     353          299 :     fn get_base(&self) -> &ffi::ELF_Note {
     354          299 :         self.ptr.as_ref().unwrap().as_ref()
     355          299 :     }
     356              : }
     357              : 
     358              : impl FromFFI<ffi::ELF_CorePrStatus> for PrStatus<'_> {
     359          104 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::ELF_CorePrStatus>) -> Self {
     360          104 :         Self {
     361          104 :             ptr,
     362          104 :             _owner: PhantomData,
     363          104 :         }
     364          104 :     }
     365              : }
     366              : 
     367              : impl std::fmt::Debug for PrStatus<'_> {
     368           78 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     369           78 :         let base = self as &dyn NoteBase;
     370           78 :         f.debug_struct("CorePrStatus")
     371           78 :             .field("base", &base)
     372           78 :             //.field("architecture", &self.architecture())
     373           78 :             //.field("status", &self.status())
     374           78 :             .finish()
     375           78 :     }
     376              : }
        

Generated by: LCOV version 2.1-1