split into modules
This commit is contained in:
parent
89f562fa86
commit
3ede0398eb
91
crates/goblin-pyo3/src/exports.rs
Normal file
91
crates/goblin-pyo3/src/exports.rs
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
#[pyclass]
|
||||||
|
enum ExportTyp {
|
||||||
|
#[default]
|
||||||
|
Regular,
|
||||||
|
Reexport,
|
||||||
|
Stub
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
#[pyclass]
|
||||||
|
struct ExportInfo {
|
||||||
|
#[pyo3(get)]
|
||||||
|
typ: ExportTyp,
|
||||||
|
#[pyo3(get)]
|
||||||
|
address: u64,
|
||||||
|
#[pyo3(get)]
|
||||||
|
flags: u64,
|
||||||
|
#[pyo3(get)]
|
||||||
|
lib: String,
|
||||||
|
#[pyo3(get)]
|
||||||
|
lib_symbol_name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<goblin::mach::exports::ExportInfo<'_>> for ExportInfo {
|
||||||
|
fn from(info: goblin::mach::exports::ExportInfo) -> Self {
|
||||||
|
use goblin::mach::exports::ExportInfo::*;
|
||||||
|
match info {
|
||||||
|
Regular { address, flags } => {
|
||||||
|
Self {
|
||||||
|
typ: ExportTyp::Regular,
|
||||||
|
address,
|
||||||
|
flags,
|
||||||
|
.. Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reexport { lib, lib_symbol_name, flags } => {
|
||||||
|
Self {
|
||||||
|
typ: ExportTyp::Reexport,
|
||||||
|
lib: lib.to_string(),
|
||||||
|
lib_symbol_name: lib_symbol_name.map(|s| s.to_string()),
|
||||||
|
flags,
|
||||||
|
.. Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Stub {
|
||||||
|
flags, ..
|
||||||
|
} => {
|
||||||
|
Self {
|
||||||
|
typ: ExportTyp::Stub,
|
||||||
|
flags,
|
||||||
|
.. Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[pyclass]
|
||||||
|
pub struct Export {
|
||||||
|
#[pyo3(get)]
|
||||||
|
name: String,
|
||||||
|
#[pyo3(get)]
|
||||||
|
info: ExportInfo,
|
||||||
|
#[pyo3(get)]
|
||||||
|
size: usize,
|
||||||
|
#[pyo3(get)]
|
||||||
|
offset: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl Export {
|
||||||
|
fn __repr__(&self) -> String {
|
||||||
|
format!("{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<goblin::mach::exports::Export<'_>> for Export {
|
||||||
|
fn from(export: goblin::mach::exports::Export) -> Self {
|
||||||
|
Self {
|
||||||
|
name: export.name,
|
||||||
|
info: export.info.into(),
|
||||||
|
size: export.size,
|
||||||
|
offset: export.offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
44
crates/goblin-pyo3/src/header.rs
Normal file
44
crates/goblin-pyo3/src/header.rs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
#[pyclass]
|
||||||
|
pub struct Header {
|
||||||
|
#[pyo3(get)]
|
||||||
|
magic: u32,
|
||||||
|
#[pyo3(get)]
|
||||||
|
cputype: u32,
|
||||||
|
#[pyo3(get)]
|
||||||
|
cpusubtype: u32,
|
||||||
|
#[pyo3(get)]
|
||||||
|
filetype: u32,
|
||||||
|
#[pyo3(get)]
|
||||||
|
ncmds: usize,
|
||||||
|
#[pyo3(get)]
|
||||||
|
sizeofcmds: u32,
|
||||||
|
#[pyo3(get)]
|
||||||
|
flags: u32,
|
||||||
|
#[pyo3(get)]
|
||||||
|
reserved: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<goblin::mach::header::Header> for Header {
|
||||||
|
fn from(other: goblin::mach::header::Header) -> Self {
|
||||||
|
Header {
|
||||||
|
magic: other.magic,
|
||||||
|
cputype: other.cputype,
|
||||||
|
cpusubtype: other.cpusubtype,
|
||||||
|
filetype: other.filetype,
|
||||||
|
ncmds: other.ncmds,
|
||||||
|
sizeofcmds: other.sizeofcmds,
|
||||||
|
flags: other.flags,
|
||||||
|
reserved: other.reserved,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl Header {
|
||||||
|
fn __repr__(&self) -> String {
|
||||||
|
format!("{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
47
crates/goblin-pyo3/src/imports.rs
Normal file
47
crates/goblin-pyo3/src/imports.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[pyclass]
|
||||||
|
pub struct Import {
|
||||||
|
#[pyo3(get)]
|
||||||
|
name: String,
|
||||||
|
#[pyo3(get)]
|
||||||
|
dylib: String,
|
||||||
|
#[pyo3(get)]
|
||||||
|
is_lazy: bool,
|
||||||
|
#[pyo3(get)]
|
||||||
|
offset: u64,
|
||||||
|
#[pyo3(get)]
|
||||||
|
size: usize,
|
||||||
|
#[pyo3(get)]
|
||||||
|
address: u64,
|
||||||
|
#[pyo3(get)]
|
||||||
|
addend: i64,
|
||||||
|
#[pyo3(get)]
|
||||||
|
is_weak: bool,
|
||||||
|
#[pyo3(get)]
|
||||||
|
start_of_sequence_offset: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl Import {
|
||||||
|
fn __repr__(&self) -> String {
|
||||||
|
format!("{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<goblin::mach::imports::Import<'_>> for Import {
|
||||||
|
fn from(import: goblin::mach::imports::Import<'_>) -> Self {
|
||||||
|
Self {
|
||||||
|
name: import.name.to_string(),
|
||||||
|
dylib: import.dylib.to_string(),
|
||||||
|
is_lazy: import.is_lazy,
|
||||||
|
offset: import.offset,
|
||||||
|
size: import.size,
|
||||||
|
address: import.address,
|
||||||
|
addend: import.addend,
|
||||||
|
is_weak: import.is_weak,
|
||||||
|
start_of_sequence_offset: import.start_of_sequence_offset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,11 +3,19 @@ use std::{
|
||||||
io::Read,
|
io::Read,
|
||||||
};
|
};
|
||||||
|
|
||||||
use goblin::{
|
use goblin::mach::Mach;
|
||||||
mach::{symbols::Nlist, Mach},
|
|
||||||
};
|
|
||||||
use pyo3::{prelude::*, exceptions::PyTypeError};
|
use pyo3::{prelude::*, exceptions::PyTypeError};
|
||||||
|
|
||||||
|
mod exports;
|
||||||
|
mod header;
|
||||||
|
mod imports;
|
||||||
|
mod symbols;
|
||||||
|
|
||||||
|
use exports::Export;
|
||||||
|
use header::Header;
|
||||||
|
use imports::Import;
|
||||||
|
use symbols::Symbols;
|
||||||
|
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
struct Object {
|
struct Object {
|
||||||
len: usize,
|
len: usize,
|
||||||
|
@ -118,280 +126,6 @@ impl Drop for Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
#[pyclass]
|
|
||||||
struct Header {
|
|
||||||
#[pyo3(get)]
|
|
||||||
magic: u32,
|
|
||||||
#[pyo3(get)]
|
|
||||||
cputype: u32,
|
|
||||||
#[pyo3(get)]
|
|
||||||
cpusubtype: u32,
|
|
||||||
#[pyo3(get)]
|
|
||||||
filetype: u32,
|
|
||||||
#[pyo3(get)]
|
|
||||||
ncmds: usize,
|
|
||||||
#[pyo3(get)]
|
|
||||||
sizeofcmds: u32,
|
|
||||||
#[pyo3(get)]
|
|
||||||
flags: u32,
|
|
||||||
#[pyo3(get)]
|
|
||||||
reserved: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<goblin::mach::header::Header> for Header {
|
|
||||||
fn from(other: goblin::mach::header::Header) -> Self {
|
|
||||||
Header {
|
|
||||||
magic: other.magic,
|
|
||||||
cputype: other.cputype,
|
|
||||||
cpusubtype: other.cpusubtype,
|
|
||||||
filetype: other.filetype,
|
|
||||||
ncmds: other.ncmds,
|
|
||||||
sizeofcmds: other.sizeofcmds,
|
|
||||||
flags: other.flags,
|
|
||||||
reserved: other.reserved,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl Header {
|
|
||||||
fn __repr__(&self) -> String {
|
|
||||||
format!("{:?}", self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
#[pyclass]
|
|
||||||
struct Symbol {
|
|
||||||
#[pyo3(get)]
|
|
||||||
name: String,
|
|
||||||
|
|
||||||
meta: Nlist,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl Symbol {
|
|
||||||
#[getter]
|
|
||||||
fn typ(&self) -> &'static str {
|
|
||||||
self.meta.type_str()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn global(&self) -> bool {
|
|
||||||
self.meta.is_global()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn weak(&self) -> bool {
|
|
||||||
self.meta.is_weak()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn undefined(&self) -> bool {
|
|
||||||
self.meta.is_undefined()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[getter]
|
|
||||||
fn stab(&self) -> bool {
|
|
||||||
self.meta.is_stab()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __repr__(&self) -> String {
|
|
||||||
format!(
|
|
||||||
"Symbol {{ name: {}, global: {}, weak: {}, undefined: {}, stab: {} }}",
|
|
||||||
self.name,
|
|
||||||
self.global(),
|
|
||||||
self.weak(),
|
|
||||||
self.undefined(),
|
|
||||||
self.stab()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pyclass]
|
|
||||||
struct Symbols {
|
|
||||||
symbols: Vec<Symbol>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl Symbols {
|
|
||||||
fn __iter__(slf: PyRef<'_, Self>) -> PyResult<Py<SymbolIter>> {
|
|
||||||
let iter = SymbolIter {
|
|
||||||
inner: slf.symbols.clone().into_iter(),
|
|
||||||
};
|
|
||||||
Py::new(slf.py(), iter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<goblin::mach::symbols::SymbolIterator<'_>> for Symbols {
|
|
||||||
fn from(other: goblin::mach::symbols::SymbolIterator) -> Self {
|
|
||||||
let symbols = other
|
|
||||||
.map(|sym| {
|
|
||||||
let (symname, meta) = sym.unwrap();
|
|
||||||
Symbol {
|
|
||||||
name: symname.to_string(),
|
|
||||||
meta,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Symbols { symbols }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pyclass]
|
|
||||||
struct SymbolIter {
|
|
||||||
inner: std::vec::IntoIter<Symbol>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl SymbolIter {
|
|
||||||
fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
|
|
||||||
slf
|
|
||||||
}
|
|
||||||
|
|
||||||
fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<Symbol> {
|
|
||||||
slf.inner.next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
#[pyclass]
|
|
||||||
enum ExportTyp {
|
|
||||||
#[default]
|
|
||||||
Regular,
|
|
||||||
Reexport,
|
|
||||||
Stub
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
|
||||||
#[pyclass]
|
|
||||||
pub struct ExportInfo {
|
|
||||||
#[pyo3(get)]
|
|
||||||
typ: ExportTyp,
|
|
||||||
#[pyo3(get)]
|
|
||||||
address: u64,
|
|
||||||
#[pyo3(get)]
|
|
||||||
flags: u64,
|
|
||||||
#[pyo3(get)]
|
|
||||||
lib: String,
|
|
||||||
#[pyo3(get)]
|
|
||||||
lib_symbol_name: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<goblin::mach::exports::ExportInfo<'_>> for ExportInfo {
|
|
||||||
fn from(info: goblin::mach::exports::ExportInfo) -> Self {
|
|
||||||
use goblin::mach::exports::ExportInfo::*;
|
|
||||||
match info {
|
|
||||||
Regular { address, flags } => {
|
|
||||||
Self {
|
|
||||||
typ: ExportTyp::Regular,
|
|
||||||
address,
|
|
||||||
flags,
|
|
||||||
.. Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reexport { lib, lib_symbol_name, flags } => {
|
|
||||||
Self {
|
|
||||||
typ: ExportTyp::Reexport,
|
|
||||||
lib: lib.to_string(),
|
|
||||||
lib_symbol_name: lib_symbol_name.map(|s| s.to_string()),
|
|
||||||
flags,
|
|
||||||
.. Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Stub {
|
|
||||||
flags, ..
|
|
||||||
} => {
|
|
||||||
Self {
|
|
||||||
typ: ExportTyp::Stub,
|
|
||||||
flags,
|
|
||||||
.. Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
#[pyclass]
|
|
||||||
struct Export {
|
|
||||||
#[pyo3(get)]
|
|
||||||
name: String,
|
|
||||||
#[pyo3(get)]
|
|
||||||
info: ExportInfo,
|
|
||||||
#[pyo3(get)]
|
|
||||||
size: usize,
|
|
||||||
#[pyo3(get)]
|
|
||||||
offset: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl Export {
|
|
||||||
fn __repr__(&self) -> String {
|
|
||||||
format!("{:?}", self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<goblin::mach::exports::Export<'_>> for Export {
|
|
||||||
fn from(export: goblin::mach::exports::Export) -> Self {
|
|
||||||
Self {
|
|
||||||
name: export.name,
|
|
||||||
info: export.info.into(),
|
|
||||||
size: export.size,
|
|
||||||
offset: export.offset,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
#[pyclass]
|
|
||||||
struct Import {
|
|
||||||
#[pyo3(get)]
|
|
||||||
name: String,
|
|
||||||
#[pyo3(get)]
|
|
||||||
dylib: String,
|
|
||||||
#[pyo3(get)]
|
|
||||||
is_lazy: bool,
|
|
||||||
#[pyo3(get)]
|
|
||||||
offset: u64,
|
|
||||||
#[pyo3(get)]
|
|
||||||
size: usize,
|
|
||||||
#[pyo3(get)]
|
|
||||||
address: u64,
|
|
||||||
#[pyo3(get)]
|
|
||||||
addend: i64,
|
|
||||||
#[pyo3(get)]
|
|
||||||
is_weak: bool,
|
|
||||||
#[pyo3(get)]
|
|
||||||
start_of_sequence_offset: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymethods]
|
|
||||||
impl Import {
|
|
||||||
fn __repr__(&self) -> String {
|
|
||||||
format!("{:?}", self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<goblin::mach::imports::Import<'_>> for Import {
|
|
||||||
fn from(import: goblin::mach::imports::Import<'_>) -> Self {
|
|
||||||
Self {
|
|
||||||
name: import.name.to_string(),
|
|
||||||
dylib: import.dylib.to_string(),
|
|
||||||
is_lazy: import.is_lazy,
|
|
||||||
offset: import.offset,
|
|
||||||
size: import.size,
|
|
||||||
address: import.address,
|
|
||||||
addend: import.addend,
|
|
||||||
is_weak: import.is_weak,
|
|
||||||
start_of_sequence_offset: import.start_of_sequence_offset,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
#[pyo3(name = "goblin")]
|
#[pyo3(name = "goblin")]
|
||||||
fn py_goblin(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
fn py_goblin(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
|
||||||
|
|
99
crates/goblin-pyo3/src/symbols.rs
Normal file
99
crates/goblin-pyo3/src/symbols.rs
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
use goblin::mach::symbols::Nlist;
|
||||||
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
#[pyclass]
|
||||||
|
struct Symbol {
|
||||||
|
#[pyo3(get)]
|
||||||
|
name: String,
|
||||||
|
|
||||||
|
meta: Nlist,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl Symbol {
|
||||||
|
#[getter]
|
||||||
|
fn typ(&self) -> &'static str {
|
||||||
|
self.meta.type_str()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn global(&self) -> bool {
|
||||||
|
self.meta.is_global()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn weak(&self) -> bool {
|
||||||
|
self.meta.is_weak()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn undefined(&self) -> bool {
|
||||||
|
self.meta.is_undefined()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn stab(&self) -> bool {
|
||||||
|
self.meta.is_stab()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __repr__(&self) -> String {
|
||||||
|
format!(
|
||||||
|
"Symbol {{ name: {}, global: {}, weak: {}, undefined: {}, stab: {} }}",
|
||||||
|
self.name,
|
||||||
|
self.global(),
|
||||||
|
self.weak(),
|
||||||
|
self.undefined(),
|
||||||
|
self.stab()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
pub struct Symbols {
|
||||||
|
symbols: Vec<Symbol>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl Symbols {
|
||||||
|
fn __iter__(slf: PyRef<'_, Self>) -> PyResult<Py<SymbolIter>> {
|
||||||
|
let iter = SymbolIter {
|
||||||
|
inner: slf.symbols.clone().into_iter(),
|
||||||
|
};
|
||||||
|
Py::new(slf.py(), iter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<goblin::mach::symbols::SymbolIterator<'_>> for Symbols {
|
||||||
|
fn from(other: goblin::mach::symbols::SymbolIterator) -> Self {
|
||||||
|
let symbols = other
|
||||||
|
.map(|sym| {
|
||||||
|
let (symname, meta) = sym.unwrap();
|
||||||
|
Symbol {
|
||||||
|
name: symname.to_string(),
|
||||||
|
meta,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Symbols { symbols }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
struct SymbolIter {
|
||||||
|
inner: std::vec::IntoIter<Symbol>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl SymbolIter {
|
||||||
|
fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> {
|
||||||
|
slf
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __next__(mut slf: PyRefMut<'_, Self>) -> Option<Symbol> {
|
||||||
|
slf.inner.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue