Skip to content

Commit 0e0f9d8

Browse files
committed
Introspection: Fixes Mach-O parsing
- properly pick the correct section - clean error when fixup chains are used
1 parent ddcfc69 commit 0e0f9d8

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

pyo3-introspection/src/introspection.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use crate::model::{Class, Function, Module};
2-
use anyhow::{bail, Context, Result};
2+
use anyhow::{bail, ensure, Context, Result};
33
use goblin::elf::Elf;
4-
use goblin::mach::symbols::N_SECT;
4+
use goblin::mach::load_command::CommandVariant;
5+
use goblin::mach::symbols::{NO_SECT, N_SECT};
56
use goblin::mach::{Mach, MachO, SingleArch};
67
use goblin::pe::PE;
78
use goblin::Object;
@@ -132,6 +133,12 @@ fn find_introspection_chunks_in_macho(
132133
if !macho.little_endian {
133134
bail!("Only little endian Mach-o binaries are supported");
134135
}
136+
ensure!(
137+
!macho.load_commands.iter().any(|command| {
138+
matches!(command.command, CommandVariant::DyldChainedFixups(_))
139+
}),
140+
"Macho-o binaries with fixup chains are not supported yet, to avoid using fixup chains, use --codegen=link-arg=-no_fixup_chains option"
141+
);
135142

136143
let sections = macho
137144
.segments
@@ -140,9 +147,14 @@ fn find_introspection_chunks_in_macho(
140147
.map(|t| t.map(|s| s.0))
141148
.collect::<Result<Vec<_>, _>>()?;
142149
let mut chunks = Vec::new();
143-
for (name, nlist) in macho.symbols().flatten() {
144-
if nlist.is_global() && nlist.get_type() == N_SECT && is_introspection_symbol(name) {
145-
let section = &sections[nlist.n_sect];
150+
for symbol in macho.symbols() {
151+
let (name, nlist) = symbol?;
152+
if nlist.is_global()
153+
&& nlist.get_type() == N_SECT
154+
&& nlist.n_sect != NO_SECT as usize
155+
&& is_introspection_symbol(name)
156+
{
157+
let section = &sections[nlist.n_sect - 1]; // Sections are counted from 1
146158
let data_offset = nlist.n_value + u64::from(section.offset) - section.addr;
147159
chunks.push(read_symbol_value_with_ptr_and_len(
148160
&library_content[usize::try_from(data_offset).context("File offset overflow")?..],

0 commit comments

Comments
 (0)