Skip to content

Commit 7f107e9

Browse files
committed
Cargo Format
1 parent 0ddade1 commit 7f107e9

8 files changed

Lines changed: 217 additions & 143 deletions

File tree

crates/delink-cli/src/main.rs

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,11 @@ fn main() -> Result<()> {
190190
contains,
191191
limit,
192192
} => cmd_macho_list_cus(&input, &contains, limit),
193-
Cmd::MachoSplit { input, outdir, symtab } => {
194-
cmd_macho_split(&input, &outdir, symtab.as_deref())
195-
}
193+
Cmd::MachoSplit {
194+
input,
195+
outdir,
196+
symtab,
197+
} => cmd_macho_split(&input, &outdir, symtab.as_deref()),
196198
}
197199
}
198200

@@ -578,19 +580,20 @@ fn cmd_pe_list_cus(exe_path: &Path, pdb_path: &Path, contains: &str, limit: usiz
578580
// ---------------------------------------------------------------------------
579581

580582
fn load_macho_context(path: &Path) -> Result<delink_macho::MachoContext> {
581-
let data =
582-
std::fs::read(path).with_context(|| format!("read {}", path.display()))?;
583+
let data = std::fs::read(path).with_context(|| format!("read {}", path.display()))?;
583584
tracing::info!("loaded Mach-O ({} bytes)", data.len());
584-
delink_macho::load_macho(&data)
585-
.with_context(|| format!("load {}", path.display()))
585+
delink_macho::load_macho(&data).with_context(|| format!("load {}", path.display()))
586586
}
587587

588588
fn cmd_macho_inspect(path: &Path) -> Result<()> {
589589
let ctx = load_macho_context(path)?;
590590

591591
println!("Mach-O arch={:?}", ctx.arch);
592592
println!("\nSECTIONS");
593-
println!(" {:<20} {:<12} {:>16} {:>12} flags", "segment", "name", "addr", "size");
593+
println!(
594+
" {:<20} {:<12} {:>16} {:>12} flags",
595+
"segment", "name", "addr", "size"
596+
);
594597
for s in &ctx.sections {
595598
println!(
596599
" {:<20} {:<12} {:#016x} {:>12} 0x{:08x}",
@@ -625,12 +628,11 @@ fn cmd_macho_list_cus(path: &Path, contains: &str, limit: usize) -> Result<()> {
625628
}
626629

627630
fn cmd_macho_split(path: &Path, outdir: &Path, symtab_arg: Option<&Path>) -> Result<()> {
628-
let data =
629-
std::fs::read(path).with_context(|| format!("read {}", path.display()))?;
631+
let data = std::fs::read(path).with_context(|| format!("read {}", path.display()))?;
630632
tracing::info!("loaded Mach-O ({} bytes)", data.len());
631633

632-
let ctx = delink_macho::load_macho(&data)
633-
.with_context(|| format!("load {}", path.display()))?;
634+
let ctx =
635+
delink_macho::load_macho(&data).with_context(|| format!("load {}", path.display()))?;
634636

635637
let input_path = path.canonicalize().unwrap_or_else(|_| path.to_path_buf());
636638
let arch_str = format!("{:?}", ctx.arch);
@@ -639,40 +641,32 @@ fn cmd_macho_split(path: &Path, outdir: &Path, symtab_arg: Option<&Path>) -> Res
639641
// Load or generate the symtab
640642
// ------------------------------------------------------------------
641643
let symtab: delink_macho::symtab_json::SymtabJson = if let Some(sp) = symtab_arg {
642-
let raw = std::fs::read_to_string(sp)
643-
.with_context(|| format!("read symtab {}", sp.display()))?;
644-
serde_json::from_str(&raw)
645-
.with_context(|| format!("parse symtab {}", sp.display()))?
644+
let raw =
645+
std::fs::read_to_string(sp).with_context(|| format!("read symtab {}", sp.display()))?;
646+
serde_json::from_str(&raw).with_context(|| format!("parse symtab {}", sp.display()))?
646647
} else {
647648
delink_macho::symtab_json::generate(&data).context("generate symtab")?
648649
};
649650

650651
let n_syms: usize = symtab.values().map(|v| v.len()).sum();
651-
tracing::info!(
652-
"symtab: {} symbols → {} output files",
653-
n_syms,
654-
symtab.len(),
655-
);
652+
tracing::info!("symtab: {} symbols → {} output files", n_syms, symtab.len(),);
656653

657-
std::fs::create_dir_all(outdir)
658-
.with_context(|| format!("create {}", outdir.display()))?;
654+
std::fs::create_dir_all(outdir).with_context(|| format!("create {}", outdir.display()))?;
659655

660656
// ------------------------------------------------------------------
661657
// Write symtab.json into the output folder so the user can edit it
662658
// and re-run with --symtab.
663659
// ------------------------------------------------------------------
664660
let symtab_out = outdir.join("symtab.json");
665-
let symtab_json_str =
666-
serde_json::to_string_pretty(&symtab).context("serialize symtab")?;
661+
let symtab_json_str = serde_json::to_string_pretty(&symtab).context("serialize symtab")?;
667662
std::fs::write(&symtab_out, &symtab_json_str)
668663
.with_context(|| format!("write {}", symtab_out.display()))?;
669664
tracing::info!("symtab → {}", symtab_out.display());
670665

671666
// ------------------------------------------------------------------
672667
// Build lookup from the binary (addr/size/flags per symbol name)
673668
// ------------------------------------------------------------------
674-
let lookup = delink_macho::symtab_json::build_lookup(&data)
675-
.context("build symtab lookup")?;
669+
let lookup = delink_macho::symtab_json::build_lookup(&data).context("build symtab lookup")?;
676670

677671
// ------------------------------------------------------------------
678672
// Split using symtab grouping

crates/delink-macho/src/cu.rs

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ pub fn build_cu_index(dwarf: &Dwarf<Slice<'_>>) -> Result<MachoCuIndex> {
6868
let mut headers = dwarf.units();
6969

7070
while let Some(header) = headers.next().map_err(|e| anyhow!("DWARF units: {e}"))? {
71-
let unit = dwarf
72-
.unit(header)
73-
.map_err(|e| anyhow!("DWARF unit: {e}"))?;
71+
let unit = dwarf.unit(header).map_err(|e| anyhow!("DWARF unit: {e}"))?;
7472
if let Some(cu) = build_unit(dwarf, &unit, cu_id)? {
7573
units.push(cu);
7674
cu_id += 1;
@@ -86,10 +84,7 @@ fn build_unit(
8684
id: usize,
8785
) -> Result<Option<MachoCompilationUnit>> {
8886
let mut entries = unit.entries();
89-
let Some(root) = entries
90-
.next_dfs()
91-
.map_err(|e| anyhow!("DIE tree: {e}"))?
92-
else {
87+
let Some(root) = entries.next_dfs().map_err(|e| anyhow!("DIE tree: {e}"))? else {
9388
return Ok(None);
9489
};
9590
if root.tag() != gimli::DW_TAG_compile_unit {
@@ -104,10 +99,7 @@ fn build_unit(
10499
let mut range_iter = dwarf
105100
.unit_ranges(unit)
106101
.map_err(|e| anyhow!("unit ranges: {e}"))?;
107-
while let Some(r) = range_iter
108-
.next()
109-
.map_err(|e| anyhow!("range entry: {e}"))?
110-
{
102+
while let Some(r) = range_iter.next().map_err(|e| anyhow!("range entry: {e}"))? {
111103
if r.begin < r.end {
112104
ranges.push(r.begin..r.end);
113105
}
@@ -117,10 +109,7 @@ fn build_unit(
117109
let mut variables = Vec::new();
118110

119111
let mut entries = unit.entries();
120-
while let Some(entry) = entries
121-
.next_dfs()
122-
.map_err(|e| anyhow!("DIE entry: {e}"))?
123-
{
112+
while let Some(entry) = entries.next_dfs().map_err(|e| anyhow!("DIE entry: {e}"))? {
124113
match entry.tag() {
125114
gimli::DW_TAG_subprogram => {
126115
if let Some(f) = extract_function(dwarf, unit, entry)? {
@@ -198,8 +187,12 @@ fn extract_variable(
198187
};
199188
let name =
200189
attr_string(dwarf, unit, entry, gimli::DW_AT_name)?.unwrap_or_else(|| "<anon>".into());
201-
let linkage_name = attr_string(dwarf, unit, entry, gimli::DW_AT_linkage_name)?
202-
.or(attr_string(dwarf, unit, entry, gimli::DW_AT_MIPS_linkage_name)?);
190+
let linkage_name = attr_string(dwarf, unit, entry, gimli::DW_AT_linkage_name)?.or(attr_string(
191+
dwarf,
192+
unit,
193+
entry,
194+
gimli::DW_AT_MIPS_linkage_name,
195+
)?);
203196
let external = matches!(
204197
entry.attr_value(gimli::DW_AT_external),
205198
Some(AttributeValue::Flag(true))
@@ -227,9 +220,9 @@ fn variable_address(
227220
let mut ops = expr.operations(unit.encoding());
228221
match ops.next().map_err(|e| anyhow!("DWARF op: {e}"))? {
229222
Some(gimli::Operation::Address { address }) => Ok(Some(address)),
230-
Some(gimli::Operation::AddressIndex { index }) => {
231-
Ok(Some(dwarf.address(unit, index).map_err(|e| anyhow!("{e}"))?))
232-
}
223+
Some(gimli::Operation::AddressIndex { index }) => Ok(Some(
224+
dwarf.address(unit, index).map_err(|e| anyhow!("{e}"))?,
225+
)),
233226
_ => Ok(None),
234227
}
235228
}
@@ -241,9 +234,12 @@ fn resolve_names(
241234
entry: &DebuggingInformationEntry<Slice<'_>>,
242235
) -> Result<(Option<String>, Option<String>, bool)> {
243236
let mut name = attr_string(dwarf, unit, entry, gimli::DW_AT_name)?;
244-
let mut linkage = attr_string(dwarf, unit, entry, gimli::DW_AT_linkage_name)?.or(
245-
attr_string(dwarf, unit, entry, gimli::DW_AT_MIPS_linkage_name)?,
246-
);
237+
let mut linkage = attr_string(dwarf, unit, entry, gimli::DW_AT_linkage_name)?.or(attr_string(
238+
dwarf,
239+
unit,
240+
entry,
241+
gimli::DW_AT_MIPS_linkage_name,
242+
)?);
247243
let mut external = matches!(
248244
entry.attr_value(gimli::DW_AT_external),
249245
Some(AttributeValue::Flag(true))
@@ -302,9 +298,7 @@ fn attr_string(
302298
return Ok(None);
303299
};
304300
let val = attr.value();
305-
let s = dwarf
306-
.attr_string(unit, val)
307-
.map_err(|e| anyhow!("{e}"))?;
301+
let s = dwarf.attr_string(unit, val).map_err(|e| anyhow!("{e}"))?;
308302
Ok(Some(s.to_string_lossy().into_owned()))
309303
}
310304

crates/delink-macho/src/emit.rs

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,8 @@ pub fn emit_macho_cu(
102102
// For other architectures (PPC etc.) we emit raw bytes without synthetic
103103
// relocations — the bytes are correct but non-relocatable.
104104
let relocs_to_emit: Vec<delink_x86::recover::RecoveredReloc> = if recover_x86 {
105-
let recovery =
106-
delink_x86::recover(&fn_bytes, f.addr, f.size, &ctx.symbols).with_context(
107-
|| format!("recover relocs for '{}' at {:#x}", f.name, f.addr),
108-
)?;
105+
let recovery = delink_x86::recover(&fn_bytes, f.addr, f.size, &ctx.symbols)
106+
.with_context(|| format!("recover relocs for '{}' at {:#x}", f.name, f.addr))?;
109107
stats.instructions += recovery.diag.instructions;
110108
stats.unresolved_calls += recovery.diag.calls_unresolved;
111109
// Zero the rel32 displacement fields before appending.
@@ -142,11 +140,7 @@ pub fn emit_macho_cu(
142140
local_syms.insert(f.symbol_name().to_string(), sym_id);
143141

144142
// Emit variable labels that fall inside this function.
145-
for (var_va, var) in ctx
146-
.symbols
147-
.variables
148-
.range(f.addr..f.addr + f.size)
149-
{
143+
for (var_va, var) in ctx.symbols.variables.range(f.addr..f.addr + f.size) {
150144
if *var_va == f.addr {
151145
continue;
152146
}
@@ -187,13 +181,7 @@ pub fn emit_macho_cu(
187181
},
188182
},
189183
)
190-
.with_context(|| {
191-
format!(
192-
"add reloc at {:#x} → '{}'",
193-
f.addr + r.offset,
194-
r.target
195-
)
196-
})?;
184+
.with_context(|| format!("add reloc at {:#x} → '{}'", f.addr + r.offset, r.target))?;
197185
stats.relocations += 1;
198186
}
199187
}
@@ -336,8 +324,7 @@ pub fn split_by_symtab(
336324
) -> Result<Vec<CuOutcome>> {
337325
use crate::cu::{MachoCompilationUnit, MachoFunction};
338326

339-
std::fs::create_dir_all(out_dir)
340-
.with_context(|| format!("create {}", out_dir.display()))?;
327+
std::fs::create_dir_all(out_dir).with_context(|| format!("create {}", out_dir.display()))?;
341328

342329
let group_vec: Vec<(&String, &Vec<String>)> = symtab.iter().collect();
343330

@@ -348,9 +335,9 @@ pub fn split_by_symtab(
348335
let mut resolved: Vec<(String, u64, u64, bool)> = names
349336
.iter()
350337
.filter_map(|name| {
351-
lookup.get(name.as_str()).map(|info| {
352-
(name.clone(), info.addr, info.size, info.external)
353-
})
338+
lookup
339+
.get(name.as_str())
340+
.map(|info| (name.clone(), info.addr, info.size, info.external))
354341
})
355342
.collect();
356343
resolved.sort_by_key(|(_, addr, _, _)| *addr);
@@ -405,8 +392,7 @@ pub fn split_by_symtab(
405392
// ---------------------------------------------------------------------------
406393

407394
pub fn split_all_macho(ctx: &MachoContext, out_dir: &Path) -> Result<Vec<CuOutcome>> {
408-
std::fs::create_dir_all(out_dir)
409-
.with_context(|| format!("create {}", out_dir.display()))?;
395+
std::fs::create_dir_all(out_dir).with_context(|| format!("create {}", out_dir.display()))?;
410396

411397
let outcomes: Vec<CuOutcome> = ctx
412398
.cu_index
@@ -482,7 +468,13 @@ fn sanitize_file_stem(name: &str) -> String {
482468
};
483469
// Replace characters that are invalid in filenames.
484470
stem.chars()
485-
.map(|c| if c.is_alphanumeric() || c == '_' || c == '-' { c } else { '_' })
471+
.map(|c| {
472+
if c.is_alphanumeric() || c == '_' || c == '-' {
473+
c
474+
} else {
475+
'_'
476+
}
477+
})
486478
.collect()
487479
}
488480

crates/delink-macho/src/lib.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use std::collections::HashMap;
1212
pub mod cu;
1313
pub mod emit;
1414
pub mod stabs;
15+
pub mod symbols;
1516
pub mod symtab_json;
1617
pub mod symtab_split;
17-
pub mod symbols;
1818

1919
pub use cu::{MachoCompilationUnit, MachoCuIndex, MachoFunction, MachoVariable};
2020
pub use emit::{CuOutcome, EmitStats, SharedDataStats};
@@ -99,12 +99,7 @@ pub fn load_macho(data: &[u8]) -> Result<MachoContext> {
9999
object::Architecture::X86_64 => MachoArch::X86_64,
100100
object::Architecture::PowerPc => MachoArch::PPC,
101101
object::Architecture::PowerPc64 => MachoArch::PPC64,
102-
other => {
103-
return Err(anyhow!(
104-
"unsupported Mach-O architecture: {:?}",
105-
other
106-
))
107-
}
102+
other => return Err(anyhow!("unsupported Mach-O architecture: {:?}", other)),
108103
};
109104

110105
let little_endian = file.is_little_endian();
@@ -182,17 +177,16 @@ fn parse_sections(file: &object::File<'_>) -> Result<Vec<MachoSection>> {
182177
// ---------------------------------------------------------------------------
183178

184179
fn load_dwarf<'a>(_data: &'a [u8], file: &object::File<'a>) -> Result<Dwarf<'a>> {
185-
let load_section =
186-
|id: gimli::SectionId| -> std::result::Result<DwarfSlice<'a>, gimli::Error> {
187-
// Map ELF-style ".debug_info" → Mach-O "__debug_info"
188-
let elf_name = id.name();
189-
let macho_name = format!("__{}", &elf_name[1..]);
190-
let section_data: &'a [u8] = match file.section_by_name(&macho_name) {
191-
Some(s) => s.data().unwrap_or(b""),
192-
None => b"",
193-
};
194-
Ok(EndianSlice::new(section_data, LittleEndian))
180+
let load_section = |id: gimli::SectionId| -> std::result::Result<DwarfSlice<'a>, gimli::Error> {
181+
// Map ELF-style ".debug_info" → Mach-O "__debug_info"
182+
let elf_name = id.name();
183+
let macho_name = format!("__{}", &elf_name[1..]);
184+
let section_data: &'a [u8] = match file.section_by_name(&macho_name) {
185+
Some(s) => s.data().unwrap_or(b""),
186+
None => b"",
195187
};
188+
Ok(EndianSlice::new(section_data, LittleEndian))
189+
};
196190
gimli::Dwarf::load(load_section).map_err(|e| anyhow!("load DWARF: {e}"))
197191
}
198192

@@ -336,10 +330,7 @@ fn parse_stubs_32(data: &[u8]) -> Result<HashMap<u64, String>> {
336330
if n_strx >= str_data.len() {
337331
return None;
338332
}
339-
let end = str_data[n_strx..]
340-
.iter()
341-
.position(|&b| b == 0)
342-
.unwrap_or(0);
333+
let end = str_data[n_strx..].iter().position(|&b| b == 0).unwrap_or(0);
343334
let s = String::from_utf8_lossy(&str_data[n_strx..n_strx + end]).into_owned();
344335
if s.is_empty() {
345336
None

0 commit comments

Comments
 (0)