Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions pyo3-introspection/src/introspection.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::model::{Class, Function, Module};
use anyhow::{bail, Context, Result};
use anyhow::{bail, ensure, Context, Result};
use goblin::elf::Elf;
use goblin::mach::symbols::N_SECT;
use goblin::mach::load_command::CommandVariant;
use goblin::mach::symbols::{NO_SECT, N_SECT};
use goblin::mach::{Mach, MachO, SingleArch};
use goblin::pe::PE;
use goblin::Object;
Expand Down Expand Up @@ -132,6 +133,12 @@ fn find_introspection_chunks_in_macho(
if !macho.little_endian {
bail!("Only little endian Mach-o binaries are supported");
}
ensure!(
!macho.load_commands.iter().any(|command| {
matches!(command.command, CommandVariant::DyldChainedFixups(_))
}),
"Mach-O binaries with fixup chains are not supported yet, to avoid using fixup chains, use `--codegen=link-arg=-no_fixup_chains` option."
);

let sections = macho
.segments
Expand All @@ -140,9 +147,14 @@ fn find_introspection_chunks_in_macho(
.map(|t| t.map(|s| s.0))
.collect::<Result<Vec<_>, _>>()?;
let mut chunks = Vec::new();
for (name, nlist) in macho.symbols().flatten() {
if nlist.is_global() && nlist.get_type() == N_SECT && is_introspection_symbol(name) {
let section = &sections[nlist.n_sect];
for symbol in macho.symbols() {
let (name, nlist) = symbol?;
if nlist.is_global()
&& nlist.get_type() == N_SECT
&& nlist.n_sect != NO_SECT as usize
&& is_introspection_symbol(name)
{
let section = &sections[nlist.n_sect - 1]; // Sections are counted from 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is a correction? Why did this not hit ci?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because there was a section right after with the exact same shift between positions in memory and positions in the file (a lot of Mach-O file do not have any shift and this is the case of the binary generated by maturin/cargo in the CI)

let data_offset = nlist.n_value + u64::from(section.offset) - section.addr;
chunks.push(read_symbol_value_with_ptr_and_len(
&library_content[usize::try_from(data_offset).context("File offset overflow")?..],
Expand Down
Loading