Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  mod.rs   Sprache: unbekannt

 
Spracherkennung für: .rs vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

pub use reader::ProcfsAuxvIter;
use {
    crate::Pid,
    std::{fs::File, io::BufReader},
    thiserror::Error,
};

mod reader;

/// The type used in auxv keys and values.
#[cfg(target_pointer_width = "32")]
pub type AuxvType = u32;
/// The type used in auxv keys and values.
#[cfg(target_pointer_width = "64")]
pub type AuxvType = u64;

#[cfg(target_os = "android")]
mod consts {
    use super::AuxvType;
    pub const AT_PHDR: AuxvType = 3;
    pub const AT_PHNUM: AuxvType = 5;
    pub const AT_ENTRY: AuxvType = 9;
    pub const AT_SYSINFO_EHDR: AuxvType = 33;
}
#[cfg(not(target_os = "android"))]
mod consts {
    use super::AuxvType;
    pub const AT_PHDR: AuxvType = libc::AT_PHDR;
    pub const AT_PHNUM: AuxvType = libc::AT_PHNUM;
    pub const AT_ENTRY: AuxvType = libc::AT_ENTRY;
    pub const AT_SYSINFO_EHDR: AuxvType = libc::AT_SYSINFO_EHDR;
}

/// An auxv key-value pair.
#[derive(Debug, PartialEq, Eq)]
pub struct AuxvPair {
    pub key: AuxvType,
    pub value: AuxvType,
}

/// Auxv info that can be passed from crashing process
///
/// Since `/proc/{pid}/auxv` can sometimes be inaccessible, the calling process should prefer to transfer this
/// information directly using the Linux `getauxval()` call (if possible).
///
/// Any field that is set to `0` will be considered unset. In that case, minidump-writer might try other techniques
/// to obtain it (like reading `/proc/{pid}/auxv`).
#[repr(C)]
#[derive(Clone, Debug, Default)]
pub struct DirectAuxvDumpInfo {
    /// The value of `getauxval(AT_PHNUM)`
    pub program_header_count: AuxvType,
    /// The value of `getauxval(AT_PHDR)`
    pub program_header_address: AuxvType,
    /// The value of `getauxval(AT_SYSINFO_EHDR)`
    pub linux_gate_address: AuxvType,
    /// The value of `getauxval(AT_ENTRY)`
    pub entry_address: AuxvType,
}

impl From<DirectAuxvDumpInfo> for AuxvDumpInfo {
    fn from(f: DirectAuxvDumpInfo) -> AuxvDumpInfo {
        AuxvDumpInfo {
            program_header_count: (f.program_header_count > 0).then_some(f.program_header_count),
            program_header_address: (f.program_header_address > 0)
                .then_some(f.program_header_address),
            linux_gate_address: (f.linux_gate_address > 0).then_some(f.linux_gate_address),
            entry_address: (f.entry_address > 0).then_some(f.entry_address),
        }
    }
}

#[derive(Debug, Default)]
pub struct AuxvDumpInfo {
    program_header_count: Option<AuxvType>,
    program_header_address: Option<AuxvType>,
    linux_gate_address: Option<AuxvType>,
    entry_address: Option<AuxvType>,
}

impl AuxvDumpInfo {
    pub fn try_filling_missing_info(&mut self, pid: Pid) -> Result<(), AuxvError> {
        if self.is_complete() {
            return Ok(());
        }

        let auxv_path = format!("/proc/{pid}/auxv");
        let auxv_file = File::open(&auxv_path).map_err(|e| AuxvError::OpenError(auxv_path, e))?;

        for AuxvPair { key, value } in
            ProcfsAuxvIter::new(BufReader::new(auxv_file)).filter_map(Result::ok)
        {
            let dest_field = match key {
                consts::AT_PHNUM => &mut self.program_header_count,
                consts::AT_PHDR => &mut self.program_header_address,
                consts::AT_SYSINFO_EHDR => &mut self.linux_gate_address,
                consts::AT_ENTRY => &mut self.entry_address,
                _ => continue,
            };
            if dest_field.is_none() {
                *dest_field = Some(value);
            }
        }

        Ok(())
    }
    pub fn get_program_header_count(&self) -> Option<AuxvType> {
        self.program_header_count
    }
    pub fn get_program_header_address(&self) -> Option<AuxvType> {
        self.program_header_address
    }
    pub fn get_linux_gate_address(&self) -> Option<AuxvType> {
        self.linux_gate_address
    }
    pub fn get_entry_address(&self) -> Option<AuxvType> {
        self.entry_address
    }
    pub fn is_complete(&self) -> bool {
        self.program_header_count.is_some()
            && self.program_header_address.is_some()
            && self.linux_gate_address.is_some()
            && self.entry_address.is_some()
    }
}

#[derive(Debug, Error)]
pub enum AuxvError {
    #[error("Failed to open file {0}")]
    OpenError(String, #[source] std::io::Error),
    #[error("No auxv entry found for PID {0}")]
    NoAuxvEntryFound(Pid),
    #[error("Invalid auxv format (should not hit EOF before AT_NULL)")]
    InvalidFormat,
    #[error("IO Error")]
    IOError(#[from] std::io::Error),
}

[ Dauer der Verarbeitung: 0.42 Sekunden  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge