Skip to content

Commit

Permalink
read/macho: split object names in ObjectMap (#686)
Browse files Browse the repository at this point in the history
  • Loading branch information
philipc authored May 23, 2024
1 parent aa2f5ad commit 7b897db
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 11 deletions.
9 changes: 7 additions & 2 deletions crates/examples/src/bin/objectmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,16 @@ fn main() {
}

fn print_symbol(symbol: &object::ObjectMapEntry<'_>, map: &object::ObjectMap<'_>) {
println!(
let file = symbol.object(map);
print!(
"{:x} {:x} {} {}",
symbol.address(),
symbol.size(),
String::from_utf8_lossy(symbol.name()),
String::from_utf8_lossy(symbol.object(map)),
String::from_utf8_lossy(file.path()),
);
if let Some(member) = file.member() {
print!("({})", String::from_utf8_lossy(member));
}
println!();
}
21 changes: 17 additions & 4 deletions src/read/macho/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use crate::macho;
use crate::pod::Pod;
use crate::read::util::StringTable;
use crate::read::{
self, ObjectMap, ObjectMapEntry, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result,
SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapEntry,
SymbolScope, SymbolSection,
self, ObjectMap, ObjectMapEntry, ObjectMapFile, ObjectSymbol, ObjectSymbolTable, ReadError,
ReadRef, Result, SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap,
SymbolMapEntry, SymbolScope, SymbolSection,
};

use super::{MachHeader, MachOFile};
Expand Down Expand Up @@ -115,7 +115,20 @@ impl<'data, Mach: MachHeader, R: ReadRef<'data>> SymbolTable<'data, Mach, R> {
if let Ok(name) = nlist.name(endian, self.strings) {
if !name.is_empty() {
object = Some(objects.len());
objects.push(name);
// `N_OSO` symbol names can be either `/path/to/object.o`
// or `/path/to/archive.a(object.o)`.
let (path, member) = name
.split_last()
.and_then(|(last, head)| {
if *last != b')' {
return None;
}
let index = head.iter().position(|&x| x == b'(')?;
let (archive, rest) = head.split_at(index);
Some((archive, Some(&rest[1..])))
})
.unwrap_or((name, None));
objects.push(ObjectMapFile::new(path, member));
}
}
}
Expand Down
35 changes: 30 additions & 5 deletions src/read/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ impl<'data> SymbolMapEntry for SymbolMapName<'data> {
#[derive(Debug, Default, Clone)]
pub struct ObjectMap<'data> {
symbols: SymbolMap<ObjectMapEntry<'data>>,
objects: Vec<&'data [u8]>,
objects: Vec<ObjectMapFile<'data>>,
}

impl<'data> ObjectMap<'data> {
Expand All @@ -531,12 +531,12 @@ impl<'data> ObjectMap<'data> {

/// Get all objects in the map.
#[inline]
pub fn objects(&self) -> &[&'data [u8]] {
pub fn objects(&self) -> &[ObjectMapFile<'data>] {
&self.objects
}
}

/// An [`ObjectMap`] entry.
/// A symbol in an [`ObjectMap`].
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ObjectMapEntry<'data> {
address: u64,
Expand Down Expand Up @@ -574,8 +574,8 @@ impl<'data> ObjectMapEntry<'data> {

/// Get the object file name.
#[inline]
pub fn object(&self, map: &ObjectMap<'data>) -> &'data [u8] {
map.objects[self.object]
pub fn object<'a>(&self, map: &'a ObjectMap<'data>) -> &'a ObjectMapFile<'data> {
&map.objects[self.object]
}
}

Expand All @@ -586,6 +586,31 @@ impl<'data> SymbolMapEntry for ObjectMapEntry<'data> {
}
}

/// An object file name in an [`ObjectMap`].
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ObjectMapFile<'data> {
path: &'data [u8],
member: Option<&'data [u8]>,
}

impl<'data> ObjectMapFile<'data> {
fn new(path: &'data [u8], member: Option<&'data [u8]>) -> Self {
ObjectMapFile { path, member }
}

/// Get the path to the file containing the object.
#[inline]
pub fn path(&self) -> &'data [u8] {
self.path
}

/// If the file is an archive, get the name of the member containing the object.
#[inline]
pub fn member(&self) -> Option<&'data [u8]> {
self.member
}
}

/// An imported symbol.
///
/// Returned by [`Object::imports`].
Expand Down

0 comments on commit 7b897db

Please sign in to comment.