Skip to content

Commit

Permalink
supports skip status for library
Browse files Browse the repository at this point in the history
  • Loading branch information
mariotaku committed Jun 13, 2023
1 parent b834414 commit eae4ec3
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 106 deletions.
2 changes: 1 addition & 1 deletion common/bin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub struct BinaryInfo {
pub undefined: Vec<String>,
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LibraryInfo {
pub name: String,
pub needed: Vec<String>,
Expand Down
42 changes: 21 additions & 21 deletions common/verify/src/bin/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,9 @@ impl VerifyWithFirmware<BinVerifyResult> for BinaryInfo {
.or_else(|| self.find_library(name));
};

fn resolve_symbols<F>(
lib: &LibraryInfo,
undefined: &mut Vec<String>,
visited: &mut HashSet<String>,
lib_resolver: &F,
) where
F: Fn(&str) -> Option<LibraryInfo>,
{
undefined.retain(|symbol| !lib.has_symbol(symbol));
for needed in &lib.needed {
if visited.contains(needed) {
continue;
}
visited.insert(needed.clone());
if let Some(needed) = lib_resolver(needed) {
resolve_symbols(&needed, undefined, visited, lib_resolver);
}
}
}

for needed in &self.needed {
if let Some(lib) = find_library(needed) {
resolve_symbols(
recursive_resolve_symbols(
&lib,
&mut result.undefined_sym,
&mut visited_libs,
Expand All @@ -54,6 +34,26 @@ impl VerifyWithFirmware<BinVerifyResult> for BinaryInfo {
}
}

pub(crate) fn recursive_resolve_symbols<F>(
lib: &LibraryInfo,
undefined: &mut Vec<String>,
visited: &mut HashSet<String>,
lib_resolver: &F,
) where
F: Fn(&str) -> Option<LibraryInfo>,
{
undefined.retain(|symbol| !lib.has_symbol(symbol));
for needed in &lib.needed {
if visited.contains(needed) {
continue;
}
visited.insert(needed.clone());
if let Some(needed) = lib_resolver(needed) {
recursive_resolve_symbols(&needed, undefined, visited, lib_resolver);
}
}
}

impl BinVerifyResult {
pub fn new(name: String) -> Self {
return Self {
Expand Down
4 changes: 2 additions & 2 deletions common/verify/src/bin/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod binary;
pub(crate) mod binary;

#[derive(Debug)]
#[derive(Debug, Eq, PartialEq)]
pub struct BinVerifyResult {
pub name: String,
pub missing_lib: Vec<String>,
Expand Down
99 changes: 82 additions & 17 deletions common/verify/src/ipk/component.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,52 @@
use bin_lib::BinaryInfo;
use std::collections::HashSet;

use bin_lib::{BinaryInfo, LibraryInfo};
use fw_lib::Firmware;
use ipk_lib::Component;

use crate::ipk::ComponentVerifyResult;
use crate::{bin::BinVerifyResult, VerifyWithFirmware};
use crate::bin::binary::recursive_resolve_symbols;
use crate::ipk::{ComponentBinVerifyResult, ComponentVerifyResult};
use crate::{bin::BinVerifyResult, VerifyResult, VerifyWithFirmware};

trait ComponentImpl {
fn verify_bin(&self, bin: &BinaryInfo, firmware: &Firmware) -> BinVerifyResult;
}

impl VerifyResult for ComponentVerifyResult {
fn is_good(&self) -> bool {
if let ComponentBinVerifyResult::Failed { .. } = &self.exe {
return false;
}
for (required, result) in &self.libs {
if !required {
continue;
}
if let ComponentBinVerifyResult::Failed { .. } = result {
return false;
}
}
return true;
}
}

impl<T> ComponentImpl for Component<T> {
fn verify_bin(&self, bin: &BinaryInfo, firmware: &Firmware) -> BinVerifyResult {
let mut result = bin.verify(firmware);
let mut visited_libs: HashSet<String> = Default::default();
result.missing_lib.retain_mut(|lib| {
if let Some(lib) = self.find_lib(lib) {
result.undefined_sym.retain(|sym| !lib.has_symbol(sym));
let find_library = |name: &str| -> Option<LibraryInfo> {
return firmware
.find_library(name)
.or_else(|| self.find_lib(name).cloned());
};

recursive_resolve_symbols(
&lib,
&mut result.undefined_sym,
&mut visited_libs,
&find_library,
);
return false;
}
return true;
Expand All @@ -30,25 +62,44 @@ impl<T> VerifyWithFirmware<ComponentVerifyResult> for Component<T> {
} else {
return ComponentVerifyResult {
id: self.id.clone(),
exe: None,
exe: ComponentBinVerifyResult::Skipped {
name: String::new(),
},
libs: Default::default(),
};
};
let mut libs: Vec<(bool, BinVerifyResult)> = self
let mut libs: Vec<(bool, ComponentBinVerifyResult)> = self
.libs
.iter()
.map(|lib| {
(
self.is_required(lib),
self.verify_bin(
&BinaryInfo {
let required = self.is_required(lib);
// System library has higher precedence
if let Some(_) = firmware.find_library(&lib.name) {
return (
required,
ComponentBinVerifyResult::Skipped {
name: lib.name.clone(),
rpath: Default::default(),
needed: lib.needed.clone(),
undefined: lib.undefined.clone(),
},
firmware,
),
);
}
let verify_result = self.verify_bin(
&BinaryInfo {
name: lib.name.clone(),
rpath: Default::default(),
needed: lib.needed.clone(),
undefined: lib.undefined.clone(),
},
firmware,
);
(
required,
if verify_result.is_good() {
ComponentBinVerifyResult::Ok {
name: verify_result.name,
}
} else {
ComponentBinVerifyResult::Failed(verify_result)
},
)
})
.collect();
Expand All @@ -57,12 +108,26 @@ impl<T> VerifyWithFirmware<ComponentVerifyResult> for Component<T> {
if !required_cmp.is_eq() {
return required_cmp.reverse();
}
return lib_a.name.cmp(&lib_b.name);
return lib_a.name().cmp(&lib_b.name());
});
return ComponentVerifyResult {
id: self.id.clone(),
exe: Some(exe),
exe: if exe.is_good() {
ComponentBinVerifyResult::Ok { name: exe.name }
} else {
ComponentBinVerifyResult::Failed(exe)
},
libs,
};
}
}

impl ComponentBinVerifyResult {
pub fn name(&self) -> &str {
return match self {
ComponentBinVerifyResult::Skipped { name } => name,
ComponentBinVerifyResult::Ok { name } => name,
ComponentBinVerifyResult::Failed(result) => &result.name,
};
}
}
13 changes: 10 additions & 3 deletions common/verify/src/ipk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ipk_lib::Package;

use crate::{bin::BinVerifyResult, VerifyWithFirmware};

mod component;
pub mod component;

#[derive(Debug)]
pub struct PackageVerifyResult {
Expand All @@ -14,8 +14,15 @@ pub struct PackageVerifyResult {
#[derive(Debug)]
pub struct ComponentVerifyResult {
pub id: String,
pub exe: Option<BinVerifyResult>,
pub libs: Vec<(bool, BinVerifyResult)>,
pub exe: ComponentBinVerifyResult,
pub libs: Vec<(bool, ComponentBinVerifyResult)>,
}

#[derive(Debug, Eq, PartialEq)]
pub enum ComponentBinVerifyResult {
Skipped { name: String },
Ok { name: String },
Failed(BinVerifyResult),
}

impl VerifyWithFirmware<PackageVerifyResult> for Package {
Expand Down
2 changes: 1 addition & 1 deletion packages/fw-extract/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::path::PathBuf;
use std::process::exit;

use clap::Parser;
use regex::Regex;
use fw_lib::FirmwareInfo;
use regex::Regex;

mod extractor;

Expand Down
Loading

0 comments on commit eae4ec3

Please sign in to comment.