Skip to content

Commit

Permalink
elf: Simplify hwcap error handling
Browse files Browse the repository at this point in the history
The hwcap_supported now returns an error, which also required
refactor auxv module to return an std::io::error.  The procfs
possible access failures are not reported to caller.
  • Loading branch information
zatrazz committed Jan 24, 2023
1 parent 4e0c7bd commit b97fe72
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src/elf/ld_so_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ fn parse_ld_so_cache_new<R: Read + Seek>(
parse_ld_so_cache_glibc_hwcap(reader, &mut prev_off, hdr.extension_offset as i64)?;

// And obtain the current machine supported glibc-hwcap subfolder.
let hwcap_supported = hwcap::hwcap_supported();
let hwcap_supported = hwcap::hwcap_supported()?;

let mut ldsocache = LdCache::new();
// Keep track of the last glibc-hwcap value for the entry to allow check if the new entry is
Expand Down
58 changes: 28 additions & 30 deletions src/elf/ld_so_cache/hwcap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub mod cpuid {
&& extended.has_avx512vl()
}

pub fn supported() -> Vec<&'static str> {
pub fn supported() -> Result<Vec<&'static str>, std::io::Error> {
let mut r = vec![];

let cpuid = CpuId::new();
Expand All @@ -68,7 +68,7 @@ pub mod cpuid {
r.push("x86-64-v2");
}
}
r
Ok(r)
}
}

Expand All @@ -81,17 +81,16 @@ pub mod cpuid {
pub const PPC_FEATURE2_ARCH_3_1: auxv::AuxvType = 0x00040000; // ISA 3.1
pub const PPC_FEATURE2_MMA: auxv::AuxvType = 0x00020000; // Matrix-Multiply Assist

pub fn supported() -> Vec<&'static str> {
pub fn supported() -> Result<Vec<&'static str>, std::io::Error> {
let mut r = vec![];
if let Ok(hwcap2) = auxv::getauxval(auxv::AT_HWCAP2) {
if hwcap2 & PPC_FEATURE2_ARCH_3_00 != 0 && hwcap2 & PPC_FEATURE2_HAS_IEEE128 != 0 {
r.push("power9");
}
if hwcap2 & PPC_FEATURE2_ARCH_3_1 != 0 && hwcap2 & PPC_FEATURE2_MMA != 0 {
r.push("power10");
}
let hwcap2 = auxv::getauxval(auxv::AT_HWCAP2)?;
if hwcap2 & PPC_FEATURE2_ARCH_3_00 != 0 && hwcap2 & PPC_FEATURE2_HAS_IEEE128 != 0 {
r.push("power9");
}
r
if hwcap2 & PPC_FEATURE2_ARCH_3_1 != 0 && hwcap2 & PPC_FEATURE2_MMA != 0 {
r.push("power10");
}
Ok(r)
}
}

Expand All @@ -108,26 +107,25 @@ pub mod cpuid {
pub const HWCAP_S390_VXRS_PDE: auxv::AuxvType = 1 << 16;
pub const HWCAP_S390_VXRS_PDE2: auxv::AuxvType = 1 << 19;

pub fn supported() -> Vec<&'static str> {
pub fn supported() -> Result<Vec<&'static str>, std::io::Error> {
let mut r = vec![];
if let Ok(hwcap) = auxv::getauxval(auxv::AT_HWCAP) {
if hwcap & HWCAP_S390_VX != 0 {
r.push("z13");
}
if hwcap & HWCAP_S390_VXD != 0
&& hwcap & HWCAP_S390_VXE != 0
&& hwcap & HWCAP_S390_GS != 0
{
r.push("z14");
}
if hwcap & HWCAP_S390_VXRS_EXT2 != 0 && hwcap & HWCAP_S390_VXRS_PDE != 0 {
r.push("z15");
}
if hwcap & HWCAP_S390_VXRS_PDE2 != 0 {
r.push("z16");
}
let hwcap = auxv::getauxval(auxv::AT_HWCAP)?;
if hwcap & HWCAP_S390_VX != 0 {
r.push("z13");
}
if hwcap & HWCAP_S390_VXD != 0
&& hwcap & HWCAP_S390_VXE != 0
&& hwcap & HWCAP_S390_GS != 0
{
r.push("z14");
}
if hwcap & HWCAP_S390_VXRS_EXT2 != 0 && hwcap & HWCAP_S390_VXRS_PDE != 0 {
r.push("z15");
}
if hwcap & HWCAP_S390_VXRS_PDE2 != 0 {
r.push("z16");
}
r
Ok(r)
}
}

Expand All @@ -146,6 +144,6 @@ pub mod cpuid {
}
}

pub fn hwcap_supported() -> Vec<&'static str> {
pub fn hwcap_supported() -> Result<Vec<&'static str>, std::io::Error> {
cpuid::supported()
}
33 changes: 10 additions & 23 deletions src/elf/ld_so_cache/hwcap/cpuid/auxv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// - Provide getauxval similar to libc signature.

use std::fs::File;
use std::io::{BufReader, Read};
use std::io::{BufReader, Read, Error, ErrorKind};
use std::path::Path;

#[cfg(target_pointer_width = "32")]
Expand All @@ -24,14 +24,7 @@ pub struct AuxvPair {
pub value: AuxvType,
}

#[derive(Debug)]
pub enum ProcfsAuxvError {
IoError,
InvalidFormat,
NotFound,
}

pub fn getauxval(key: AuxvType) -> Result<AuxvType, ProcfsAuxvError> {
pub fn getauxval(key: AuxvType) -> Result<AuxvType, std::io::Error> {
for r in iterate_path(&Path::new("/proc/self/auxv"))? {
let pair = match r {
Ok(p) => p,
Expand All @@ -42,7 +35,8 @@ pub fn getauxval(key: AuxvType) -> Result<AuxvType, ProcfsAuxvError> {
return Ok(pair.value);
}
}
Err(ProcfsAuxvError::NotFound)
//Err(ProcfsAuxvError::NotFound)
Err(Error::new(ErrorKind::Other, "auxv entry not found"))
}

pub struct ProcfsAuxvIter<R: Read> {
Expand All @@ -52,9 +46,8 @@ pub struct ProcfsAuxvIter<R: Read> {
keep_going: bool,
}

fn iterate_path(path: &Path) -> Result<ProcfsAuxvIter<File>, ProcfsAuxvError> {
fn iterate_path(path: &Path) -> Result<ProcfsAuxvIter<File>, std::io::Error> {
let input = File::open(path)
.map_err(|_| ProcfsAuxvError::IoError)
.map(|f| BufReader::new(f))?;

let pair_size = 2 * std::mem::size_of::<AuxvType>();
Expand All @@ -69,7 +62,7 @@ fn iterate_path(path: &Path) -> Result<ProcfsAuxvIter<File>, ProcfsAuxvError> {
}

impl<R: Read> Iterator for ProcfsAuxvIter<R> {
type Item = Result<AuxvPair, ProcfsAuxvError>;
type Item = Result<AuxvPair, std::io::Error>;
fn next(&mut self) -> Option<Self::Item> {
if !self.keep_going {
return None;
Expand All @@ -87,24 +80,18 @@ impl<R: Read> Iterator for ProcfsAuxvIter<R> {
Ok(n) => {
if n == 0 {
// should not hit EOF before AT_NULL
return Some(Err(ProcfsAuxvError::InvalidFormat));
return Some(Err(Error::new(ErrorKind::Other, "invalid auxv format")));
}

read_bytes += n;
}
Err(_) => return Some(Err(ProcfsAuxvError::IoError)),
Err(e) => return Some(Err(e))
}
}

let mut reader = &self.buf[..];
let aux_key = match read_long(&mut reader) {
Ok(x) => x,
Err(_) => return Some(Err(ProcfsAuxvError::InvalidFormat)),
};
let aux_val = match read_long(&mut reader) {
Ok(x) => x,
Err(_) => return Some(Err(ProcfsAuxvError::InvalidFormat)),
};
let aux_key = read_long(&mut reader).ok()?;
let aux_val = read_long(&mut reader).ok()?;

// AT_NULL (0) signals the end of auxv
if aux_key == 0 {
Expand Down

0 comments on commit b97fe72

Please sign in to comment.