Skip to content

Commit

Permalink
Extract ZIP-embedded path splitting into a function
Browse files Browse the repository at this point in the history
  • Loading branch information
sudoBash418 committed Sep 8, 2024
1 parent 960e60a commit d747ba3
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 16 deletions.
17 changes: 16 additions & 1 deletion src/symbolize/gimli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use core::convert::TryInto;
use core::mem;
use core::u32;
use libc::c_void;
use mystd::ffi::OsString;
use mystd::ffi::{OsStr, OsString};
use mystd::fs::File;
use mystd::path::Path;
use mystd::prelude::v1::*;
Expand Down Expand Up @@ -322,6 +322,21 @@ fn create_mapping(lib: &Library) -> Option<Mapping> {
}
}

/// Try to extract the archive path from an "embedded" library path
/// (e.g. `/path/to/my.apk` from `/path/to/my.apk!/mylib.so`).
///
/// Returns `None` if the path does not contain a `!/` separator.
#[cfg(target_os = "android")]
fn extract_zip_path_android(path: &OsStr) -> Option<&OsStr> {
use mystd::os::unix::ffi::OsStrExt;

path.as_bytes()
.windows(2)
.enumerate()
.find(|(_, chunk)| chunk == b"!/")
.map(|(index, _)| OsStr::from_bytes(path.as_bytes().split_at(index).0))
}

// unsafe because this is required to be externally synchronized
pub unsafe fn clear_symbol_cache() {
Cache::with_global(|cache| cache.mappings.clear());
Expand Down
7 changes: 1 addition & 6 deletions src/symbolize/gimli/elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,7 @@ impl Mapping {
pub fn new_android(path: &Path, zip_offset: Option<u64>) -> Option<Mapping> {
fn map_embedded_library(path: &Path, zip_offset: u64) -> Option<Mapping> {
// get path of ZIP archive (delimited by `!/`)
let raw_path = path.as_os_str().as_bytes();
let zip_path = raw_path
.windows(2)
.enumerate()
.find(|(_, chunk)| chunk == b"!/")
.map(|(index, _)| Path::new(OsStr::from_bytes(raw_path.split_at(index).0)))?;
let zip_path = Path::new(super::extract_zip_path_android(path.as_os_str())?);

let file = fs::File::open(zip_path).ok()?;
let len = file.metadata().ok()?.len();
Expand Down
15 changes: 6 additions & 9 deletions src/symbolize/gimli/libs_dl_iterate_phdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,12 @@ unsafe extern "C" fn callback(
// only check for ZIP-embedded file if we have data from /proc/self/maps
maps.as_ref().and_then(|maps| {
// check if file is embedded within a ZIP archive by searching for `!/`
name.as_bytes()
.windows(2)
.find(|&chunk| chunk == b"!/")
.and_then(|_| {
// find MapsEntry matching library's base address
maps.iter()
.find(|m| m.ip_matches(dlpi_addr as usize))
.and_then(|m| Some(m.offset()))
})
super::extract_zip_path_android(&name).and_then(|_| {
// find MapsEntry matching library's base address and get its file offset
maps.iter()
.find(|m| m.ip_matches(dlpi_addr as usize))
.map(|m| m.offset())
})
})
};
let headers = if dlpi_phdr.is_null() || dlpi_phnum == 0 {
Expand Down

0 comments on commit d747ba3

Please sign in to comment.