Migrate SectionIndex/SymbolIndex to u32

This halves the size of structs like SectionAddress.
This commit is contained in:
Luke Street 2024-10-04 20:40:50 -06:00
parent 1f4b452bd5
commit b184fee73f
24 changed files with 263 additions and 215 deletions

View File

@ -16,12 +16,15 @@ use crate::{
vm::{BranchTarget, GprValue, StepResult, VM}, vm::{BranchTarget, GprValue, StepResult, VM},
RelocationTarget, RelocationTarget,
}, },
obj::{ObjInfo, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind}, obj::{
ObjInfo, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind,
SectionIndex,
},
}; };
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SectionAddress { pub struct SectionAddress {
pub section: usize, pub section: SectionIndex,
pub address: u32, pub address: u32,
} }
@ -38,7 +41,7 @@ impl Display for SectionAddress {
} }
impl SectionAddress { impl SectionAddress {
pub fn new(section: usize, address: u32) -> Self { Self { section, address } } pub fn new(section: SectionIndex, address: u32) -> Self { Self { section, address } }
pub fn offset(self, offset: i32) -> Self { pub fn offset(self, offset: i32) -> Self {
Self { section: self.section, address: self.address.wrapping_add_signed(offset) } Self { section: self.section, address: self.address.wrapping_add_signed(offset) }
@ -116,7 +119,7 @@ pub struct AnalyzerState {
pub functions: BTreeMap<SectionAddress, FunctionInfo>, pub functions: BTreeMap<SectionAddress, FunctionInfo>,
pub jump_tables: BTreeMap<SectionAddress, u32>, pub jump_tables: BTreeMap<SectionAddress, u32>,
pub known_symbols: BTreeMap<SectionAddress, Vec<ObjSymbol>>, pub known_symbols: BTreeMap<SectionAddress, Vec<ObjSymbol>>,
pub known_sections: BTreeMap<usize, String>, pub known_sections: BTreeMap<SectionIndex, String>,
} }
impl AnalyzerState { impl AnalyzerState {

View File

@ -18,7 +18,7 @@ struct VisitedAddresses {
impl VisitedAddresses { impl VisitedAddresses {
pub fn new(obj: &ObjInfo) -> Self { pub fn new(obj: &ObjInfo) -> Self {
let mut inner = Vec::with_capacity(obj.sections.len()); let mut inner = Vec::with_capacity(obj.sections.len() as usize);
for (_, section) in obj.sections.iter() { for (_, section) in obj.sections.iter() {
if section.kind == ObjSectionKind::Code { if section.kind == ObjSectionKind::Code {
let size = (section.size / 4) as usize; let size = (section.size / 4) as usize;
@ -32,11 +32,13 @@ impl VisitedAddresses {
} }
pub fn contains(&self, section_address: u32, address: SectionAddress) -> bool { pub fn contains(&self, section_address: u32, address: SectionAddress) -> bool {
self.inner[address.section].contains(Self::bit_for(section_address, address.address)) self.inner[address.section as usize]
.contains(Self::bit_for(section_address, address.address))
} }
pub fn insert(&mut self, section_address: u32, address: SectionAddress) { pub fn insert(&mut self, section_address: u32, address: SectionAddress) {
self.inner[address.section].insert(Self::bit_for(section_address, address.address)); self.inner[address.section as usize]
.insert(Self::bit_for(section_address, address.address));
} }
#[inline] #[inline]

View File

@ -6,7 +6,9 @@ use ppc750cl::Ins;
use crate::{ use crate::{
analysis::cfa::SectionAddress, analysis::cfa::SectionAddress,
array_ref, array_ref,
obj::{ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbolKind}, obj::{
ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbolKind, SectionIndex,
},
}; };
pub mod cfa; pub mod cfa;
@ -36,11 +38,9 @@ fn read_unresolved_relocation_address(
address: u32, address: u32,
reloc_kind: Option<ObjRelocKind>, reloc_kind: Option<ObjRelocKind>,
) -> Result<Option<RelocationTarget>> { ) -> Result<Option<RelocationTarget>> {
if let Some(reloc) = obj if let Some(reloc) = obj.unresolved_relocations.iter().find(|reloc| {
.unresolved_relocations reloc.section as SectionIndex == section.elf_index && reloc.address == address
.iter() }) {
.find(|reloc| reloc.section as usize == section.elf_index && reloc.address == address)
{
if reloc.module_id != obj.module_id { if reloc.module_id != obj.module_id {
return Ok(Some(RelocationTarget::External)); return Ok(Some(RelocationTarget::External));
} }
@ -48,7 +48,7 @@ fn read_unresolved_relocation_address(
ensure!(reloc.kind == reloc_kind); ensure!(reloc.kind == reloc_kind);
} }
let (target_section_index, target_section) = let (target_section_index, target_section) =
obj.sections.get_elf_index(reloc.target_section as usize).ok_or_else(|| { obj.sections.get_elf_index(reloc.target_section as SectionIndex).ok_or_else(|| {
anyhow!( anyhow!(
"Failed to find target section {} for unresolved relocation", "Failed to find target section {} for unresolved relocation",
reloc.target_section reloc.target_section

View File

@ -1,7 +1,7 @@
use anyhow::Result; use anyhow::Result;
use crate::{ use crate::{
obj::{ObjDataKind, ObjInfo, ObjSectionKind, ObjSymbolKind}, obj::{ObjDataKind, ObjInfo, ObjSectionKind, ObjSymbolKind, SymbolIndex},
util::split::is_linker_generated_label, util::split::is_linker_generated_label,
}; };
@ -64,7 +64,7 @@ pub fn detect_objects(obj: &mut ObjInfo) -> Result<()> {
} }
pub fn detect_strings(obj: &mut ObjInfo) -> Result<()> { pub fn detect_strings(obj: &mut ObjInfo) -> Result<()> {
let mut symbols_set = Vec::<(usize, ObjDataKind, usize)>::new(); let mut symbols_set = Vec::<(SymbolIndex, ObjDataKind, usize)>::new();
for (section_index, section) in obj for (section_index, section) in obj
.sections .sections
.iter() .iter()

View File

@ -7,7 +7,7 @@ use crate::{
analysis::cfa::{AnalyzerState, FunctionInfo, SectionAddress}, analysis::cfa::{AnalyzerState, FunctionInfo, SectionAddress},
obj::{ obj::{
ObjInfo, ObjKind, ObjRelocKind, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjInfo, ObjKind, ObjRelocKind, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet,
ObjSymbolFlags, ObjSymbolKind, ObjSymbolFlags, ObjSymbolKind, SectionIndex,
}, },
}; };
@ -147,14 +147,14 @@ impl AnalysisPass for FindRelCtorsDtors {
// And the section ends with a null pointer // And the section ends with a null pointer
while let Some(reloc) = obj.unresolved_relocations.iter().find(|reloc| { while let Some(reloc) = obj.unresolved_relocations.iter().find(|reloc| {
reloc.module_id == obj.module_id reloc.module_id == obj.module_id
&& reloc.section == section.elf_index as u8 && reloc.section as SectionIndex == section.elf_index
&& reloc.address == current_address && reloc.address == current_address
&& reloc.kind == ObjRelocKind::Absolute && reloc.kind == ObjRelocKind::Absolute
}) { }) {
let Some((target_section_index, target_section)) = obj let Some((target_section_index, target_section)) =
.sections obj.sections.iter().find(|(_, section)| {
.iter() section.elf_index == reloc.target_section as SectionIndex
.find(|(_, section)| section.elf_index == reloc.target_section as usize) })
else { else {
return false; return false;
}; };

View File

@ -19,7 +19,7 @@ use crate::{
}, },
obj::{ obj::{
ObjDataKind, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjDataKind, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind,
ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, SectionIndex, SymbolIndex,
}, },
}; };
@ -298,7 +298,7 @@ impl Tracker {
debug_assert_ne!( debug_assert_ne!(
value, value,
RelocationTarget::Address(SectionAddress::new( RelocationTarget::Address(SectionAddress::new(
usize::MAX, SectionIndex::MAX,
0 0
)) ))
); );
@ -359,7 +359,7 @@ impl Tracker {
debug_assert_ne!( debug_assert_ne!(
address, address,
RelocationTarget::Address(SectionAddress::new( RelocationTarget::Address(SectionAddress::new(
usize::MAX, SectionIndex::MAX,
0 0
)) ))
); );
@ -380,7 +380,7 @@ impl Tracker {
debug_assert_ne!( debug_assert_ne!(
address, address,
RelocationTarget::Address(SectionAddress::new( RelocationTarget::Address(SectionAddress::new(
usize::MAX, SectionIndex::MAX,
0 0
)) ))
); );
@ -464,7 +464,7 @@ impl Tracker {
{ {
(addr, is_function_addr(addr)) (addr, is_function_addr(addr))
} else { } else {
(SectionAddress::new(usize::MAX, 0), false) (SectionAddress::new(SectionIndex::MAX, 0), false)
}; };
if branch.link || !is_fn_addr { if branch.link || !is_fn_addr {
self.relocations.insert(ins_addr, match ins.op { self.relocations.insert(ins_addr, match ins.op {
@ -549,7 +549,7 @@ impl Tracker {
fn process_data( fn process_data(
&mut self, &mut self,
obj: &ObjInfo, obj: &ObjInfo,
section_index: usize, section_index: SectionIndex,
section: &ObjSection, section: &ObjSection,
) -> Result<()> { ) -> Result<()> {
let mut addr = SectionAddress::new(section_index, section.address as u32); let mut addr = SectionAddress::new(section_index, section.address as u32);
@ -602,7 +602,7 @@ impl Tracker {
} else { } else {
// Check known relocations (function signature matching) // Check known relocations (function signature matching)
if self.known_relocations.contains(&from) { if self.known_relocations.contains(&from) {
return Some(SectionAddress::new(usize::MAX, addr)); return Some(SectionAddress::new(SectionIndex::MAX, addr));
} }
// Check special symbols // Check special symbols
if self.stack_address == Some(addr) if self.stack_address == Some(addr)
@ -613,7 +613,7 @@ impl Tracker {
|| self.sda2_base == Some(addr) || self.sda2_base == Some(addr)
|| self.sda_base == Some(addr) || self.sda_base == Some(addr)
{ {
return Some(SectionAddress::new(usize::MAX, addr)); return Some(SectionAddress::new(SectionIndex::MAX, addr));
} }
// Not valid // Not valid
None None
@ -625,7 +625,7 @@ impl Tracker {
obj: &mut ObjInfo, obj: &mut ObjInfo,
addr: u32, addr: u32,
reloc_kind: ObjRelocKind, reloc_kind: ObjRelocKind,
) -> Option<usize> { ) -> Option<SymbolIndex> {
if !matches!( if !matches!(
reloc_kind, reloc_kind,
ObjRelocKind::PpcAddr16Ha | ObjRelocKind::PpcAddr16Lo ObjRelocKind::PpcAddr16Ha | ObjRelocKind::PpcAddr16Lo
@ -641,7 +641,7 @@ impl Tracker {
// return generate_special_symbol(obj, addr, &name).ok(); // return generate_special_symbol(obj, addr, &name).ok();
// } // }
// } // }
let mut check_symbol = |opt: Option<u32>, name: &str| -> Option<usize> { let mut check_symbol = |opt: Option<u32>, name: &str| -> Option<SymbolIndex> {
if let Some(value) = opt { if let Some(value) = opt {
if addr == value { if addr == value {
return generate_special_symbol(obj, value, name).ok(); return generate_special_symbol(obj, value, name).ok();
@ -866,7 +866,7 @@ fn data_kind_from_op(op: Opcode) -> DataKind {
} }
} }
fn generate_special_symbol(obj: &mut ObjInfo, addr: u32, name: &str) -> Result<usize> { fn generate_special_symbol(obj: &mut ObjInfo, addr: u32, name: &str) -> Result<SymbolIndex> {
obj.add_symbol( obj.add_symbol(
ObjSymbol { ObjSymbol {
name: name.to_string(), name: name.to_string(),

View File

@ -34,7 +34,7 @@ use crate::{
cmd::shasum::file_sha1_string, cmd::shasum::file_sha1_string,
obj::{ obj::{
best_match_for_reloc, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSectionKind, ObjSymbol, best_match_for_reloc, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSectionKind, ObjSymbol,
ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, SymbolIndex, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, SectionIndex, SymbolIndex,
}, },
util::{ util::{
asm::write_asm, asm::write_asm,
@ -402,7 +402,7 @@ pub fn run(args: Args) -> Result<()> {
fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> { fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> {
let rso = process_rso(&mut Cursor::new(buf))?; let rso = process_rso(&mut Cursor::new(buf))?;
for symbol in rso.symbols.iter() { for (_, symbol) in rso.symbols.iter() {
let dol_section_index = match symbol.section { let dol_section_index = match symbol.section {
Some(section) => section, Some(section) => section,
None => bail!( None => bail!(
@ -411,15 +411,17 @@ fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> {
symbol.address symbol.address
), ),
}; };
let (section, address, section_kind) = if dol_section_index == DOL_SECTION_ABS as usize { let (section, address, section_kind) = if dol_section_index
== DOL_SECTION_ABS as SectionIndex
{
(None, symbol.address as u32, None) (None, symbol.address as u32, None)
} else { } else {
let dol_section_name = if dol_section_index == DOL_SECTION_ETI as usize { let dol_section_name = if dol_section_index == DOL_SECTION_ETI as SectionIndex {
"extabindex" "extabindex"
} else { } else {
DOL_SECTION_NAMES.get(dol_section_index).and_then(|&opt| opt).ok_or_else(|| { DOL_SECTION_NAMES.get(dol_section_index as usize).and_then(|&opt| opt).ok_or_else(
anyhow!("Can't add symbol for unknown DOL section {}", dol_section_index) || anyhow!("Can't add symbol for unknown DOL section {}", dol_section_index),
})? )?
}; };
let (dol_section_index, dol_section) = obj let (dol_section_index, dol_section) = obj
.sections .sections
@ -577,7 +579,7 @@ fn update_symbols(
if source_module_id == obj.module_id { if source_module_id == obj.module_id {
// Skip if already resolved // Skip if already resolved
let (_, source_section) = let (_, source_section) =
obj.sections.get_elf_index(rel_reloc.section as usize).ok_or_else(|| { obj.sections.get_elf_index(rel_reloc.section as SectionIndex).ok_or_else(|| {
anyhow!( anyhow!(
"Failed to locate REL section {} in module ID {}: source module {}, {:?}", "Failed to locate REL section {} in module ID {}: source module {}, {:?}",
rel_reloc.section, rel_reloc.section,
@ -591,8 +593,10 @@ fn update_symbols(
} }
} }
let (target_section_index, target_section) = let (target_section_index, target_section) = obj
obj.sections.get_elf_index(rel_reloc.target_section as usize).ok_or_else(|| { .sections
.get_elf_index(rel_reloc.target_section as SectionIndex)
.ok_or_else(|| {
anyhow!( anyhow!(
"Failed to locate REL section {} in module ID {}: source module {}, {:?}", "Failed to locate REL section {} in module ID {}: source module {}, {:?}",
rel_reloc.target_section, rel_reloc.target_section,
@ -655,7 +659,7 @@ fn create_relocations(
for rel_reloc in take(&mut obj.unresolved_relocations) { for rel_reloc in take(&mut obj.unresolved_relocations) {
// Skip if already resolved // Skip if already resolved
let (_, source_section) = let (_, source_section) =
obj.sections.get_elf_index(rel_reloc.section as usize).ok_or_else(|| { obj.sections.get_elf_index(rel_reloc.section as SectionIndex).ok_or_else(|| {
anyhow!( anyhow!(
"Failed to locate REL section {} in module ID {}: {:?}", "Failed to locate REL section {} in module ID {}: {:?}",
rel_reloc.section, rel_reloc.section,
@ -683,7 +687,7 @@ fn create_relocations(
anyhow!("Failed to locate DOL section at {:#010X}", rel_reloc.addend) anyhow!("Failed to locate DOL section at {:#010X}", rel_reloc.addend)
})? })?
} else { } else {
target_obj.sections.get_elf_index(rel_reloc.target_section as usize).ok_or_else( target_obj.sections.get_elf_index(rel_reloc.target_section as SectionIndex).ok_or_else(
|| { || {
anyhow!( anyhow!(
"Failed to locate module {} section {}", "Failed to locate module {} section {}",
@ -720,7 +724,7 @@ fn create_relocations(
}, },
}; };
let (_, source_section) = let (_, source_section) =
obj.sections.get_elf_index_mut(rel_reloc.section as usize).unwrap(); obj.sections.get_elf_index_mut(rel_reloc.section as SectionIndex).unwrap();
source_section.relocations.insert(rel_reloc.address, reloc)?; source_section.relocations.insert(rel_reloc.address, reloc)?;
} }
@ -739,7 +743,7 @@ fn resolve_external_relocations(
module_id: u32, module_id: u32,
symbol_index: SymbolIndex, symbol_index: SymbolIndex,
} }
let mut reloc_to_symbol = HashMap::<RelocRef, usize>::new(); let mut reloc_to_symbol = HashMap::<RelocRef, SymbolIndex>::new();
for (_section_index, section) in obj.sections.iter_mut() { for (_section_index, section) in obj.sections.iter_mut() {
for (_reloc_address, reloc) in section.relocations.iter_mut() { for (_reloc_address, reloc) in section.relocations.iter_mut() {
@ -1572,7 +1576,7 @@ fn diff(args: DiffArgs) -> Result<()> {
let linked_obj = process_elf(&args.elf_file)?; let linked_obj = process_elf(&args.elf_file)?;
let common_bss = obj.sections.common_bss_start(); let common_bss = obj.sections.common_bss_start();
for orig_sym in obj.symbols.iter().filter(|s| { for (_, orig_sym) in obj.symbols.iter().filter(|(_, s)| {
!matches!(s.kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section) && !s.flags.is_stripped() !matches!(s.kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section) && !s.flags.is_stripped()
}) { }) {
let Some(orig_section_index) = orig_sym.section else { continue }; let Some(orig_section_index) = orig_sym.section else { continue };
@ -1596,8 +1600,8 @@ fn diff(args: DiffArgs) -> Result<()> {
if linked_sym.size != orig_sym.size && if linked_sym.size != orig_sym.size &&
// TODO validate common symbol sizes // TODO validate common symbol sizes
// (need to account for inflation bug) // (need to account for inflation bug)
matches!(common_bss, Some((idx, addr)) if matches!(common_bss, Some(addr) if
orig_section_index == idx && orig_sym.address as u32 >= addr) orig_section_index == addr.section && orig_sym.address as u32 >= addr.address)
{ {
log::error!( log::error!(
"Expected {} (type {:?}) to have size {:#X}, but found {:#X}", "Expected {} (type {:?}) to have size {:#X}, but found {:#X}",
@ -1656,7 +1660,7 @@ fn diff(args: DiffArgs) -> Result<()> {
} }
// Data diff // Data diff
for orig_sym in obj.symbols.iter().filter(|s| { for (_, orig_sym) in obj.symbols.iter().filter(|(_, s)| {
s.size > 0 && !matches!(s.kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section) s.size > 0 && !matches!(s.kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section)
}) { }) {
let Some(orig_section_index) = orig_sym.section else { continue }; let Some(orig_section_index) = orig_sym.section else { continue };
@ -1756,7 +1760,7 @@ fn apply(args: ApplyArgs) -> Result<()> {
let linked_obj = process_elf(&args.elf_file)?; let linked_obj = process_elf(&args.elf_file)?;
let mut replacements: Vec<(SymbolIndex, Option<ObjSymbol>)> = vec![]; let mut replacements: Vec<(SymbolIndex, Option<ObjSymbol>)> = vec![];
for (orig_idx, orig_sym) in obj.symbols.iter().enumerate() { for (orig_idx, orig_sym) in obj.symbols.iter() {
// skip ABS for now // skip ABS for now
if orig_sym.section.is_none() { if orig_sym.section.is_none() {
continue; continue;
@ -1832,7 +1836,7 @@ fn apply(args: ApplyArgs) -> Result<()> {
} }
// Add symbols from the linked object that aren't in the original // Add symbols from the linked object that aren't in the original
for linked_sym in linked_obj.symbols.iter() { for (_, linked_sym) in linked_obj.symbols.iter() {
if matches!(linked_sym.kind, ObjSymbolKind::Section) if matches!(linked_sym.kind, ObjSymbolKind::Section)
|| is_auto_symbol(linked_sym) || is_auto_symbol(linked_sym)
|| is_linker_generated_object(&linked_sym.name) || is_linker_generated_object(&linked_sym.name)

View File

@ -28,7 +28,10 @@ use crate::{
}, },
array_ref_mut, array_ref_mut,
cmd::dol::{find_object_base, ModuleConfig, ObjectBase, ProjectConfig}, cmd::dol::{find_object_base, ModuleConfig, ObjectBase, ProjectConfig},
obj::{ObjInfo, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol}, obj::{
ObjInfo, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol,
SectionIndex as ObjSectionIndex,
},
util::{ util::{
config::{is_auto_symbol, read_splits_sections, SectionDef}, config::{is_auto_symbol, read_splits_sections, SectionDef},
dol::process_dol, dol::process_dol,
@ -499,7 +502,7 @@ fn merge(args: MergeArgs) -> Result<()> {
} }
log::info!("Merging {} REL(s)", processed); log::info!("Merging {} REL(s)", processed);
let mut section_map: BTreeMap<u32, BTreeMap<u32, u32>> = BTreeMap::new(); let mut section_map: BTreeMap<u32, BTreeMap<ObjSectionIndex, u32>> = BTreeMap::new();
let mut offset = align32(arena_lo + 0x2000); let mut offset = align32(arena_lo + 0x2000);
for module in module_map.values() { for module in module_map.values() {
for (mod_section_index, mod_section) in module.sections.iter() { for (mod_section_index, mod_section) in module.sections.iter() {
@ -518,7 +521,7 @@ fn merge(args: MergeArgs) -> Result<()> {
section_known: mod_section.section_known, section_known: mod_section.section_known,
splits: mod_section.splits.clone(), splits: mod_section.splits.clone(),
}); });
section_map.nested_insert(module.module_id, mod_section.elf_index as u32, offset)?; section_map.nested_insert(module.module_id, mod_section.elf_index, offset)?;
for (_, mod_symbol) in module.symbols.for_section(mod_section_index) { for (_, mod_symbol) in module.symbols.for_section(mod_section_index) {
obj.symbols.add_direct(ObjSymbol { obj.symbols.add_direct(ObjSymbol {
name: mod_symbol.name.clone(), name: mod_symbol.name.clone(),
@ -542,7 +545,8 @@ fn merge(args: MergeArgs) -> Result<()> {
log::info!("Applying REL relocations"); log::info!("Applying REL relocations");
for module in module_map.values() { for module in module_map.values() {
for rel_reloc in &module.unresolved_relocations { for rel_reloc in &module.unresolved_relocations {
let source_addr = (section_map[&module.module_id][&(rel_reloc.section as u32)] let source_addr = (section_map[&module.module_id]
[&(rel_reloc.section as ObjSectionIndex)]
+ rel_reloc.address) + rel_reloc.address)
& !3; & !3;
let target_addr = if rel_reloc.module_id == 0 { let target_addr = if rel_reloc.module_id == 0 {

View File

@ -13,7 +13,9 @@ use std::{
use anyhow::{anyhow, bail, ensure, Result}; use anyhow::{anyhow, bail, ensure, Result};
use objdiff_core::obj::split_meta::SplitMeta; use objdiff_core::obj::split_meta::SplitMeta;
pub use relocations::{ObjReloc, ObjRelocKind, ObjRelocations}; pub use relocations::{ObjReloc, ObjRelocKind, ObjRelocations};
pub use sections::{section_kind_for_section, ObjSection, ObjSectionKind, ObjSections}; pub use sections::{
section_kind_for_section, ObjSection, ObjSectionKind, ObjSections, SectionIndex,
};
pub use splits::{ObjSplit, ObjSplits}; pub use splits::{ObjSplit, ObjSplits};
pub use symbols::{ pub use symbols::{
best_match_for_reloc, ObjDataKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, best_match_for_reloc, ObjDataKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind,
@ -132,7 +134,12 @@ impl ObjInfo {
self.symbols.add(in_symbol, replace) self.symbols.add(in_symbol, replace)
} }
pub fn add_split(&mut self, section_index: usize, address: u32, split: ObjSplit) -> Result<()> { pub fn add_split(
&mut self,
section_index: SectionIndex,
address: u32,
split: ObjSplit,
) -> Result<()> {
let section = self let section = self
.sections .sections
.get_mut(section_index) .get_mut(section_index)
@ -322,8 +329,8 @@ impl ObjInfo {
// Include common symbols // Include common symbols
self.symbols self.symbols
.iter() .iter()
.filter(|&symbol| symbol.flags.is_common()) .filter(|&(_, symbol)| symbol.flags.is_common())
.map(|s| s.size as u32), .map(|(_, s)| s.size as u32),
) )
.sum() .sum()
} }

View File

@ -7,7 +7,10 @@ use std::{
use anyhow::{anyhow, bail, ensure, Result}; use anyhow::{anyhow, bail, ensure, Result};
use itertools::Itertools; use itertools::Itertools;
use crate::obj::{ObjKind, ObjRelocations, ObjSplit, ObjSplits, ObjSymbol}; use crate::{
analysis::cfa::SectionAddress,
obj::{ObjKind, ObjRelocations, ObjSplit, ObjSplits, ObjSymbol},
};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum ObjSectionKind { pub enum ObjSectionKind {
@ -26,7 +29,7 @@ pub struct ObjSection {
pub data: Vec<u8>, pub data: Vec<u8>,
pub align: u64, pub align: u64,
/// REL files reference the original ELF section indices /// REL files reference the original ELF section indices
pub elf_index: usize, pub elf_index: SectionIndex,
pub relocations: ObjRelocations, pub relocations: ObjRelocations,
pub virtual_address: Option<u64>, pub virtual_address: Option<u64>,
pub file_offset: u64, pub file_offset: u64,
@ -40,38 +43,45 @@ pub struct ObjSections {
sections: Vec<ObjSection>, sections: Vec<ObjSection>,
} }
pub type SectionIndex = u32;
impl ObjSections { impl ObjSections {
pub fn new(obj_kind: ObjKind, sections: Vec<ObjSection>) -> Self { Self { obj_kind, sections } } pub fn new(obj_kind: ObjKind, sections: Vec<ObjSection>) -> Self { Self { obj_kind, sections } }
pub fn iter(&self) -> impl DoubleEndedIterator<Item = (usize, &ObjSection)> { pub fn iter(&self) -> impl DoubleEndedIterator<Item = (SectionIndex, &ObjSection)> {
self.sections.iter().enumerate() self.sections.iter().enumerate().map(|(i, s)| (i as SectionIndex, s))
} }
pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (usize, &mut ObjSection)> { pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (SectionIndex, &mut ObjSection)> {
self.sections.iter_mut().enumerate() self.sections.iter_mut().enumerate().map(|(i, s)| (i as SectionIndex, s))
} }
pub fn len(&self) -> usize { self.sections.len() } pub fn len(&self) -> SectionIndex { self.sections.len() as SectionIndex }
pub fn is_empty(&self) -> bool { self.sections.is_empty() } pub fn is_empty(&self) -> bool { self.sections.is_empty() }
pub fn next_section_index(&self) -> usize { self.sections.len() } pub fn next_section_index(&self) -> SectionIndex { self.sections.len() as SectionIndex }
pub fn get(&self, index: usize) -> Option<&ObjSection> { self.sections.get(index) } pub fn get(&self, index: SectionIndex) -> Option<&ObjSection> {
self.sections.get(index as usize)
pub fn get_mut(&mut self, index: usize) -> Option<&mut ObjSection> {
self.sections.get_mut(index)
} }
pub fn get_elf_index(&self, elf_index: usize) -> Option<(usize, &ObjSection)> { pub fn get_mut(&mut self, index: SectionIndex) -> Option<&mut ObjSection> {
self.sections.get_mut(index as usize)
}
pub fn get_elf_index(&self, elf_index: SectionIndex) -> Option<(SectionIndex, &ObjSection)> {
self.iter().find(|&(_, s)| s.elf_index == elf_index) self.iter().find(|&(_, s)| s.elf_index == elf_index)
} }
pub fn get_elf_index_mut(&mut self, elf_index: usize) -> Option<(usize, &mut ObjSection)> { pub fn get_elf_index_mut(
&mut self,
elf_index: SectionIndex,
) -> Option<(SectionIndex, &mut ObjSection)> {
self.iter_mut().find(|(_, s)| s.elf_index == elf_index) self.iter_mut().find(|(_, s)| s.elf_index == elf_index)
} }
pub fn at_address(&self, addr: u32) -> Result<(usize, &ObjSection)> { pub fn at_address(&self, addr: u32) -> Result<(SectionIndex, &ObjSection)> {
ensure!( ensure!(
self.obj_kind == ObjKind::Executable, self.obj_kind == ObjKind::Executable,
"Use of ObjSections::at_address in relocatable object" "Use of ObjSections::at_address in relocatable object"
@ -81,7 +91,7 @@ impl ObjSections {
.ok_or_else(|| anyhow!("Failed to locate section @ {:#010X}", addr)) .ok_or_else(|| anyhow!("Failed to locate section @ {:#010X}", addr))
} }
pub fn at_address_mut(&mut self, addr: u32) -> Result<(usize, &mut ObjSection)> { pub fn at_address_mut(&mut self, addr: u32) -> Result<(SectionIndex, &mut ObjSection)> {
ensure!( ensure!(
self.obj_kind == ObjKind::Executable, self.obj_kind == ObjKind::Executable,
"Use of ObjSections::at_address_mut in relocatable object" "Use of ObjSections::at_address_mut in relocatable object"
@ -91,7 +101,7 @@ impl ObjSections {
.ok_or_else(|| anyhow!("Failed to locate section @ {:#010X}", addr)) .ok_or_else(|| anyhow!("Failed to locate section @ {:#010X}", addr))
} }
pub fn with_range(&self, range: Range<u32>) -> Result<(usize, &ObjSection)> { pub fn with_range(&self, range: Range<u32>) -> Result<(SectionIndex, &ObjSection)> {
ensure!( ensure!(
self.obj_kind == ObjKind::Executable, self.obj_kind == ObjKind::Executable,
"Use of ObjSections::with_range in relocatable object" "Use of ObjSections::with_range in relocatable object"
@ -104,46 +114,52 @@ impl ObjSections {
pub fn by_kind( pub fn by_kind(
&self, &self,
kind: ObjSectionKind, kind: ObjSectionKind,
) -> impl DoubleEndedIterator<Item = (usize, &ObjSection)> { ) -> impl DoubleEndedIterator<Item = (SectionIndex, &ObjSection)> {
self.iter().filter(move |(_, s)| s.kind == kind) self.iter().filter(move |(_, s)| s.kind == kind)
} }
pub fn by_name(&self, name: &str) -> Result<Option<(usize, &ObjSection)>> { pub fn by_name(&self, name: &str) -> Result<Option<(SectionIndex, &ObjSection)>> {
self.iter() self.iter()
.filter(move |(_, s)| s.name == name) .filter(move |(_, s)| s.name == name)
.at_most_one() .at_most_one()
.map_err(|_| anyhow!("Multiple sections with name {}", name)) .map_err(|_| anyhow!("Multiple sections with name {}", name))
} }
pub fn push(&mut self, section: ObjSection) -> usize { pub fn push(&mut self, section: ObjSection) -> SectionIndex {
let index = self.sections.len(); let index = self.sections.len();
self.sections.push(section); self.sections.push(section);
index index as SectionIndex
} }
pub fn all_splits( pub fn all_splits(
&self, &self,
) -> impl DoubleEndedIterator<Item = (usize, &ObjSection, u32, &ObjSplit)> { ) -> impl DoubleEndedIterator<Item = (SectionIndex, &ObjSection, u32, &ObjSplit)> {
self.iter() self.iter()
.flat_map(|(idx, s)| s.splits.iter().map(move |(addr, split)| (idx, s, addr, split))) .flat_map(|(idx, s)| s.splits.iter().map(move |(addr, split)| (idx, s, addr, split)))
} }
pub fn common_bss_start(&self) -> Option<(usize, u32)> { pub fn common_bss_start(&self) -> Option<SectionAddress> {
let Ok(Some((section_index, section))) = self.by_name(".bss") else { let Ok(Some((section_index, section))) = self.by_name(".bss") else {
return None; return None;
}; };
section.splits.iter().find(|(_, split)| split.common).map(|(addr, _)| (section_index, addr)) section
.splits
.iter()
.find(|(_, split)| split.common)
.map(|(addr, _)| SectionAddress::new(section_index, addr))
} }
} }
impl Index<usize> for ObjSections { impl Index<SectionIndex> for ObjSections {
type Output = ObjSection; type Output = ObjSection;
fn index(&self, index: usize) -> &Self::Output { &self.sections[index] } fn index(&self, index: SectionIndex) -> &Self::Output { &self.sections[index as usize] }
} }
impl IndexMut<usize> for ObjSections { impl IndexMut<SectionIndex> for ObjSections {
fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.sections[index] } fn index_mut(&mut self, index: SectionIndex) -> &mut Self::Output {
&mut self.sections[index as usize]
}
} }
impl ObjSection { impl ObjSection {

View File

@ -4,7 +4,7 @@ use anyhow::{anyhow, Result};
use itertools::Itertools; use itertools::Itertools;
use crate::{ use crate::{
obj::{ObjInfo, ObjSection}, obj::{ObjInfo, ObjSection, SectionIndex},
util::{nested::NestedVec, split::default_section_align}, util::{nested::NestedVec, split::default_section_align},
}; };
@ -28,7 +28,7 @@ impl ObjSplit {
pub fn alignment( pub fn alignment(
&self, &self,
obj: &ObjInfo, obj: &ObjInfo,
section_index: usize, section_index: SectionIndex,
section: &ObjSection, section: &ObjSection,
split_addr: u32, split_addr: u32,
) -> u32 { ) -> u32 {

View File

@ -12,7 +12,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::{ use crate::{
analysis::cfa::SectionAddress, analysis::cfa::SectionAddress,
obj::{ObjKind, ObjRelocKind, ObjSections}, obj::{sections::SectionIndex, ObjKind, ObjRelocKind, ObjSections},
util::{ util::{
config::{is_auto_jump_table, is_auto_label, is_auto_symbol, parse_u32}, config::{is_auto_jump_table, is_auto_label, is_auto_symbol, parse_u32},
nested::NestedVec, nested::NestedVec,
@ -187,7 +187,7 @@ pub struct ObjSymbol {
pub name: String, pub name: String,
pub demangled_name: Option<String>, pub demangled_name: Option<String>,
pub address: u64, pub address: u64,
pub section: Option<usize>, pub section: Option<SectionIndex>,
pub size: u64, pub size: u64,
pub size_known: bool, pub size_known: bool,
pub flags: ObjSymbolFlagSet, pub flags: ObjSymbolFlagSet,
@ -199,7 +199,7 @@ pub struct ObjSymbol {
pub demangled_name_hash: Option<u32>, pub demangled_name_hash: Option<u32>,
} }
pub type SymbolIndex = usize; pub type SymbolIndex = u32;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ObjSymbols { pub struct ObjSymbols {
@ -216,8 +216,10 @@ impl ObjSymbols {
let mut symbols_by_section: Vec<BTreeMap<u32, Vec<SymbolIndex>>> = vec![]; let mut symbols_by_section: Vec<BTreeMap<u32, Vec<SymbolIndex>>> = vec![];
let mut symbols_by_name = HashMap::<String, Vec<SymbolIndex>>::new(); let mut symbols_by_name = HashMap::<String, Vec<SymbolIndex>>::new();
for (idx, symbol) in symbols.iter().enumerate() { for (idx, symbol) in symbols.iter().enumerate() {
let idx = idx as SymbolIndex;
symbols_by_address.nested_push(symbol.address as u32, idx); symbols_by_address.nested_push(symbol.address as u32, idx);
if let Some(section_idx) = symbol.section { if let Some(section_idx) = symbol.section {
let section_idx = section_idx as usize;
if section_idx >= symbols_by_section.len() { if section_idx >= symbols_by_section.len() {
symbols_by_section.resize_with(section_idx + 1, BTreeMap::new); symbols_by_section.resize_with(section_idx + 1, BTreeMap::new);
} }
@ -312,7 +314,7 @@ impl ObjSymbols {
} }
symbol_idx symbol_idx
} else { } else {
let target_symbol_idx = self.symbols.len(); let target_symbol_idx = self.symbols.len() as SymbolIndex;
self.add_direct(ObjSymbol { self.add_direct(ObjSymbol {
name: in_symbol.name, name: in_symbol.name,
demangled_name: in_symbol.demangled_name, demangled_name: in_symbol.demangled_name,
@ -333,9 +335,10 @@ impl ObjSymbols {
} }
pub fn add_direct(&mut self, in_symbol: ObjSymbol) -> Result<SymbolIndex> { pub fn add_direct(&mut self, in_symbol: ObjSymbol) -> Result<SymbolIndex> {
let symbol_idx = self.symbols.len(); let symbol_idx = self.symbols.len() as SymbolIndex;
self.symbols_by_address.nested_push(in_symbol.address as u32, symbol_idx); self.symbols_by_address.nested_push(in_symbol.address as u32, symbol_idx);
if let Some(section_idx) = in_symbol.section { if let Some(section_idx) = in_symbol.section {
let section_idx = section_idx as usize;
if section_idx >= self.symbols_by_section.len() { if section_idx >= self.symbols_by_section.len() {
self.symbols_by_section.resize_with(section_idx + 1, BTreeMap::new); self.symbols_by_section.resize_with(section_idx + 1, BTreeMap::new);
} }
@ -355,28 +358,30 @@ impl ObjSymbols {
Ok(symbol_idx) Ok(symbol_idx)
} }
pub fn iter(&self) -> impl DoubleEndedIterator<Item = &ObjSymbol> { self.symbols.iter() } pub fn iter(&self) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> {
self.symbols.iter().enumerate().map(|(i, s)| (i as SymbolIndex, s))
}
pub fn count(&self) -> usize { self.symbols.len() } pub fn count(&self) -> SymbolIndex { self.symbols.len() as SymbolIndex }
pub fn at_section_address( pub fn at_section_address(
&self, &self,
section_idx: usize, section_idx: SectionIndex,
addr: u32, addr: u32,
) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> { ) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> {
self.symbols_by_section self.symbols_by_section
.get(section_idx) .get(section_idx as usize)
.and_then(|v| v.get(&addr)) .and_then(|v| v.get(&addr))
.into_iter() .into_iter()
.flatten() .flatten()
.map(move |&idx| (idx, &self.symbols[idx])) .map(move |&idx| (idx, &self.symbols[idx as usize]))
// "Stripped" symbols don't actually exist at the address // "Stripped" symbols don't actually exist at the address
.filter(|(_, sym)| !sym.flags.is_stripped()) .filter(|(_, sym)| !sym.flags.is_stripped())
} }
pub fn kind_at_section_address( pub fn kind_at_section_address(
&self, &self,
section_idx: usize, section_idx: SectionIndex,
addr: u32, addr: u32,
kind: ObjSymbolKind, kind: ObjSymbolKind,
) -> Result<Option<(SymbolIndex, &ObjSymbol)>> { ) -> Result<Option<(SymbolIndex, &ObjSymbol)>> {
@ -397,7 +402,7 @@ impl ObjSymbols {
self.symbols_by_section self.symbols_by_section
.iter() .iter()
.flat_map(|v| v.iter().map(|(_, v)| v)) .flat_map(|v| v.iter().map(|(_, v)| v))
.flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u]))) .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u as usize])))
} }
// Iterate over all ABS symbols // Iterate over all ABS symbols
@ -405,24 +410,24 @@ impl ObjSymbols {
debug_assert!(self.obj_kind == ObjKind::Executable); debug_assert!(self.obj_kind == ObjKind::Executable);
self.symbols_by_address self.symbols_by_address
.iter() .iter()
.flat_map(|(_, v)| v.iter().map(|&u| (u, &self.symbols[u]))) .flat_map(|(_, v)| v.iter().map(|&u| (u, &self.symbols[u as usize])))
.filter(|(_, s)| s.section.is_none()) .filter(|(_, s)| s.section.is_none())
} }
// Iterate over range in address ascending order, excluding ABS symbols // Iterate over range in address ascending order, excluding ABS symbols
pub fn for_section_range<R>( pub fn for_section_range<R>(
&self, &self,
section_index: usize, section_index: SectionIndex,
range: R, range: R,
) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> ) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)>
where where
R: RangeBounds<u32> + Clone, R: RangeBounds<u32> + Clone,
{ {
self.symbols_by_section self.symbols_by_section
.get(section_index) .get(section_index as usize)
.into_iter() .into_iter()
.flat_map(move |v| v.range(range.clone())) .flat_map(move |v| v.range(range.clone()))
.flat_map(move |(_, v)| v.iter().map(move |u| (*u, &self.symbols[*u]))) .flat_map(move |(_, v)| v.iter().map(move |u| (*u, &self.symbols[*u as usize])))
} }
pub fn indexes_for_range<R>( pub fn indexes_for_range<R>(
@ -438,13 +443,13 @@ impl ObjSymbols {
pub fn for_section( pub fn for_section(
&self, &self,
section_idx: usize, section_idx: SectionIndex,
) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> { ) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> {
self.symbols_by_section self.symbols_by_section
.get(section_idx) .get(section_idx as usize)
.into_iter() .into_iter()
.flat_map(|v| v.iter().map(|(_, v)| v)) .flat_map(|v| v.iter().map(|(_, v)| v))
.flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u]))) .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u as usize])))
} }
pub fn for_name( pub fn for_name(
@ -454,7 +459,7 @@ impl ObjSymbols {
self.symbols_by_name self.symbols_by_name
.get(name) .get(name)
.into_iter() .into_iter()
.flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u]))) .flat_map(move |v| v.iter().map(move |u| (*u, &self.symbols[*u as usize])))
} }
pub fn by_name(&self, name: &str) -> Result<Option<(SymbolIndex, &ObjSymbol)>> { pub fn by_name(&self, name: &str) -> Result<Option<(SymbolIndex, &ObjSymbol)>> {
@ -515,11 +520,11 @@ impl ObjSymbols {
&self, &self,
kind: ObjSymbolKind, kind: ObjSymbolKind,
) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> { ) -> impl DoubleEndedIterator<Item = (SymbolIndex, &ObjSymbol)> {
self.symbols.iter().enumerate().filter(move |(_, sym)| sym.kind == kind) self.iter().filter(move |(_, sym)| sym.kind == kind)
} }
pub fn replace(&mut self, index: SymbolIndex, symbol: ObjSymbol) -> Result<()> { pub fn replace(&mut self, index: SymbolIndex, symbol: ObjSymbol) -> Result<()> {
let symbol_ref = &mut self.symbols[index]; let symbol_ref = &mut self.symbols[index as usize];
ensure!(symbol_ref.address == symbol.address, "Can't modify address with replace_symbol"); ensure!(symbol_ref.address == symbol.address, "Can't modify address with replace_symbol");
ensure!(symbol_ref.section == symbol.section, "Can't modify section with replace_symbol"); ensure!(symbol_ref.section == symbol.section, "Can't modify section with replace_symbol");
if symbol_ref.name != symbol.name { if symbol_ref.name != symbol.name {
@ -545,7 +550,7 @@ impl ObjSymbols {
for (_addr, symbol_idxs) in self.indexes_for_range(..=target_addr.address).rev() { for (_addr, symbol_idxs) in self.indexes_for_range(..=target_addr.address).rev() {
let symbols = symbol_idxs let symbols = symbol_idxs
.iter() .iter()
.map(|&idx| (idx, &self.symbols[idx])) .map(|&idx| (idx, &self.symbols[idx as usize]))
.filter(|(_, sym)| { .filter(|(_, sym)| {
(sym.section.is_none() || sym.section == Some(target_addr.section)) (sym.section.is_none() || sym.section == Some(target_addr.section))
&& sym.referenced_by(reloc_kind) && sym.referenced_by(reloc_kind)
@ -570,14 +575,14 @@ impl ObjSymbols {
#[inline] #[inline]
pub fn flags(&mut self, idx: SymbolIndex) -> &mut ObjSymbolFlagSet { pub fn flags(&mut self, idx: SymbolIndex) -> &mut ObjSymbolFlagSet {
&mut self.symbols[idx].flags &mut self.symbols[idx as usize].flags
} }
} }
impl Index<SymbolIndex> for ObjSymbols { impl Index<SymbolIndex> for ObjSymbols {
type Output = ObjSymbol; type Output = ObjSymbol;
fn index(&self, index: usize) -> &Self::Output { &self.symbols[index] } fn index(&self, index: SymbolIndex) -> &Self::Output { &self.symbols[index as usize] }
} }
impl ObjSymbol { impl ObjSymbol {

View File

@ -7,7 +7,7 @@ use anyhow::Result;
use io::{Error, ErrorKind}; use io::{Error, ErrorKind};
use crate::{ use crate::{
obj::{ObjSymbol, ObjSymbolKind}, obj::{ObjSymbol, ObjSymbolKind, SectionIndex},
util::{ util::{
dol::{DolLike, DolSection, DolSectionKind}, dol::{DolLike, DolSection, DolSectionKind},
reader::{ reader::{
@ -55,7 +55,7 @@ impl FromReader for AlfFile {
data_size: section.data_size, data_size: section.data_size,
size: section.size, size: section.size,
kind, kind,
index: sections.len(), index: sections.len() as SectionIndex,
}); });
} }
for sym in &symtab.symbols { for sym in &symtab.symbols {
@ -230,7 +230,7 @@ impl AlfSymbol {
name, name,
demangled_name, demangled_name,
address: self.address as u64, address: self.address as u64,
section: Some(self.section as usize - 1), section: Some(self.section as SectionIndex - 1),
size: self.size as u64, size: self.size as u64,
size_known: true, size_known: true,
flags: Default::default(), flags: Default::default(),

View File

@ -11,7 +11,7 @@ use ppc750cl::{Argument, Ins, InsIter, Opcode};
use crate::{ use crate::{
obj::{ obj::{
ObjDataKind, ObjInfo, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol, ObjDataKind, ObjInfo, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol,
ObjSymbolKind, ObjSymbolKind, SymbolIndex,
}, },
util::nested::NestedVec, util::nested::NestedVec,
}; };
@ -25,7 +25,7 @@ enum SymbolEntryKind {
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
struct SymbolEntry { struct SymbolEntry {
index: usize, index: SymbolIndex,
kind: SymbolEntryKind, kind: SymbolEntryKind,
} }
@ -44,7 +44,7 @@ where W: Write + ?Sized {
} }
// We'll append generated symbols to the end // We'll append generated symbols to the end
let mut symbols: Vec<ObjSymbol> = obj.symbols.iter().cloned().collect(); let mut symbols: Vec<ObjSymbol> = obj.symbols.iter().map(|(_, s)| s.clone()).collect();
let mut section_entries: Vec<BTreeMap<u32, Vec<SymbolEntry>>> = vec![]; let mut section_entries: Vec<BTreeMap<u32, Vec<SymbolEntry>>> = vec![];
let mut section_relocations: Vec<BTreeMap<u32, ObjReloc>> = vec![]; let mut section_relocations: Vec<BTreeMap<u32, ObjReloc>> = vec![];
for (section_idx, section) in obj.sections.iter() { for (section_idx, section) in obj.sections.iter() {
@ -90,7 +90,7 @@ where W: Write + ?Sized {
.map(|e| e.index); .map(|e| e.index);
if target_symbol_idx.is_none() { if target_symbol_idx.is_none() {
let display_address = address as u64 + section.virtual_address.unwrap_or(0); let display_address = address as u64 + section.virtual_address.unwrap_or(0);
let symbol_idx = symbols.len(); let symbol_idx = symbols.len() as SymbolIndex;
symbols.push(ObjSymbol { symbols.push(ObjSymbol {
name: format!(".L_{display_address:08X}"), name: format!(".L_{display_address:08X}"),
address: display_address, address: display_address,
@ -131,7 +131,7 @@ where W: Write + ?Sized {
if reloc.addend == 0 { if reloc.addend == 0 {
continue; continue;
} }
let target = &symbols[reloc.target_symbol]; let target = &symbols[reloc.target_symbol as usize];
let target_section_idx = match target.section { let target_section_idx = match target.section {
Some(v) => v, Some(v) => v,
None => continue, None => continue,
@ -140,7 +140,7 @@ where W: Write + ?Sized {
anyhow!("Invalid relocation target section: {:#010X} {:?}", reloc_address, target) anyhow!("Invalid relocation target section: {:#010X} {:?}", reloc_address, target)
})?; })?;
let address = (target.address as i64 + reloc.addend) as u64; let address = (target.address as i64 + reloc.addend) as u64;
let vec = match section_entries[target_section_idx].entry(address as u32) { let vec = match section_entries[target_section_idx as usize].entry(address as u32) {
btree_map::Entry::Occupied(e) => e.into_mut(), btree_map::Entry::Occupied(e) => e.into_mut(),
btree_map::Entry::Vacant(e) => e.insert(vec![]), btree_map::Entry::Vacant(e) => e.insert(vec![]),
}; };
@ -149,7 +149,7 @@ where W: Write + ?Sized {
.any(|e| e.kind == SymbolEntryKind::Label || e.kind == SymbolEntryKind::Start) .any(|e| e.kind == SymbolEntryKind::Label || e.kind == SymbolEntryKind::Start)
{ {
let display_address = address + target_section.virtual_address.unwrap_or(0); let display_address = address + target_section.virtual_address.unwrap_or(0);
let symbol_idx = symbols.len(); let symbol_idx = symbols.len() as SymbolIndex;
symbols.push(ObjSymbol { symbols.push(ObjSymbol {
name: format!(".L_{display_address:08X}"), name: format!(".L_{display_address:08X}"),
address: display_address, address: display_address,
@ -181,13 +181,17 @@ where W: Write + ?Sized {
} }
for (section_index, section) in obj.sections.iter() { for (section_index, section) in obj.sections.iter() {
let entries = &section_entries[section_index]; let entries = &section_entries[section_index as usize];
let relocations = &section_relocations[section_index]; let relocations = &section_relocations[section_index as usize];
let mut current_address = section.address as u32; let mut current_address = section.address as u32;
let section_end = (section.address + section.size) as u32; let section_end = (section.address + section.size) as u32;
let subsection = let subsection = obj
obj.sections.iter().take(section_index).filter(|(_, s)| s.name == section.name).count(); .sections
.iter()
.take(section_index as usize)
.filter(|(_, s)| s.name == section.name)
.count();
loop { loop {
if current_address >= section_end { if current_address >= section_end {
@ -369,7 +373,7 @@ fn write_symbol_entry<W>(
where where
W: Write + ?Sized, W: Write + ?Sized,
{ {
let symbol = &symbols[entry.index]; let symbol = &symbols[entry.index as usize];
// Skip writing certain symbols // Skip writing certain symbols
if symbol.kind == ObjSymbolKind::Section { if symbol.kind == ObjSymbolKind::Section {
@ -452,13 +456,13 @@ where
} }
fn parse_extab(symbols: &[ObjSymbol], entry: &SymbolEntry, section: &ObjSection) -> Result<String> { fn parse_extab(symbols: &[ObjSymbol], entry: &SymbolEntry, section: &ObjSection) -> Result<String> {
let symbol = &symbols[entry.index]; let symbol = &symbols[entry.index as usize];
let data = section.symbol_data(symbol)?; let data = section.symbol_data(symbol)?;
let decoded = cwextab::decode_extab(data)?; let decoded = cwextab::decode_extab(data)?;
let function_names = section let function_names = section
.relocations .relocations
.range(symbol.address as u32..(symbol.address + symbol.size) as u32) .range(symbol.address as u32..(symbol.address + symbol.size) as u32)
.map(|(_, reloc)| symbols[reloc.target_symbol].name.clone()) .map(|(_, reloc)| symbols[reloc.target_symbol as usize].name.clone())
.collect_vec(); .collect_vec();
decoded.to_string(function_names).ok_or_else(|| anyhow!("Failed to print extab entry")) decoded.to_string(function_names).ok_or_else(|| anyhow!("Failed to print extab entry"))
} }
@ -504,7 +508,7 @@ where
.with_context(|| format!("At address {:#010X}", sym_addr))?; .with_context(|| format!("At address {:#010X}", sym_addr))?;
entry = entry_iter.next(); entry = entry_iter.next();
} else if current_address > sym_addr { } else if current_address > sym_addr {
let dbg_symbols = vec.iter().map(|e| &symbols[e.index]).collect_vec(); let dbg_symbols = vec.iter().map(|e| &symbols[e.index as usize]).collect_vec();
bail!( bail!(
"Unaligned symbol entry @ {:#010X}:\n\t{:?}", "Unaligned symbol entry @ {:#010X}:\n\t{:?}",
section.virtual_address.unwrap_or(0) as u32 + sym_addr, section.virtual_address.unwrap_or(0) as u32 + sym_addr,
@ -585,7 +589,7 @@ fn find_symbol_kind(
for entry in entries { for entry in entries {
match entry.kind { match entry.kind {
SymbolEntryKind::Start => { SymbolEntryKind::Start => {
let new_kind = symbols[entry.index].kind; let new_kind = symbols[entry.index as usize].kind;
if !matches!(new_kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section) { if !matches!(new_kind, ObjSymbolKind::Unknown | ObjSymbolKind::Section) {
ensure!( ensure!(
!found || new_kind == kind, !found || new_kind == kind,
@ -611,11 +615,11 @@ fn find_data_kind(
for entry in entries { for entry in entries {
match entry.kind { match entry.kind {
SymbolEntryKind::Start => { SymbolEntryKind::Start => {
let new_kind = symbols[entry.index].data_kind; let new_kind = symbols[entry.index as usize].data_kind;
if !matches!(new_kind, ObjDataKind::Unknown) { if !matches!(new_kind, ObjDataKind::Unknown) {
if found && new_kind != kind { if found && new_kind != kind {
for entry in entries { for entry in entries {
log::error!("Symbol {:?}", symbols[entry.index]); log::error!("Symbol {:?}", symbols[entry.index as usize]);
} }
bail!( bail!(
"Conflicting data kinds found: {kind:?} and {new_kind:?}", "Conflicting data kinds found: {kind:?} and {new_kind:?}",
@ -806,14 +810,14 @@ where
ObjRelocKind::Absolute => { ObjRelocKind::Absolute => {
// Attempt to use .rel macro for relative relocations // Attempt to use .rel macro for relative relocations
if reloc.addend != 0 { if reloc.addend != 0 {
let target = &symbols[reloc.target_symbol]; let target = &symbols[reloc.target_symbol as usize];
let target_addr = (target.address as i64 + reloc.addend) as u32; let target_addr = (target.address as i64 + reloc.addend) as u32;
if let Some(entry) = target if let Some(entry) = target
.section .section
.and_then(|section_idx| section_entries[section_idx].get(&target_addr)) .and_then(|section_idx| section_entries[section_idx as usize].get(&target_addr))
.and_then(|entries| entries.iter().find(|e| e.kind == SymbolEntryKind::Label)) .and_then(|entries| entries.iter().find(|e| e.kind == SymbolEntryKind::Label))
{ {
let symbol = &symbols[entry.index]; let symbol = &symbols[entry.index as usize];
write!(w, "\t.rel ")?; write!(w, "\t.rel ")?;
write_symbol_name(w, &target.name)?; write_symbol_name(w, &target.name)?;
write!(w, ", ")?; write!(w, ", ")?;
@ -959,7 +963,7 @@ fn write_reloc_symbol<W>(
where where
W: Write + ?Sized, W: Write + ?Sized,
{ {
write_symbol_name(w, &symbols[reloc.target_symbol].name)?; write_symbol_name(w, &symbols[reloc.target_symbol as usize].name)?;
match reloc.addend.cmp(&0i64) { match reloc.addend.cmp(&0i64) {
Ordering::Greater => write!(w, "+{:#X}", reloc.addend), Ordering::Greater => write!(w, "+{:#X}", reloc.addend),
Ordering::Less => write!(w, "-{:#X}", -reloc.addend), Ordering::Less => write!(w, "-{:#X}", -reloc.addend),

View File

@ -18,7 +18,7 @@ use crate::{
analysis::cfa::SectionAddress, analysis::cfa::SectionAddress,
obj::{ obj::{
ObjDataKind, ObjInfo, ObjKind, ObjSectionKind, ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjDataKind, ObjInfo, ObjKind, ObjSectionKind, ObjSplit, ObjSymbol, ObjSymbolFlagSet,
ObjSymbolFlags, ObjSymbolKind, ObjUnit, ObjSymbolFlags, ObjSymbolKind, ObjUnit, SectionIndex,
}, },
util::{ util::{
file::{buf_writer, FileReadInfo}, file::{buf_writer, FileReadInfo},
@ -621,7 +621,7 @@ fn parse_section_line(captures: Captures, state: &SplitState) -> Result<SplitLin
enum SplitState { enum SplitState {
None, None,
Sections(usize), Sections(SectionIndex),
Unit(String), Unit(String),
} }

View File

@ -40,7 +40,7 @@ pub fn process_code(
arch.process_code( arch.process_code(
symbol.address, symbol.address,
orig_data, orig_data,
section.elf_index, section.elf_index as usize,
&orig_relocs, &orig_relocs,
&Default::default(), &Default::default(),
config, config,

View File

@ -11,7 +11,7 @@ use crate::{
array_ref, array_ref,
obj::{ obj::{
ObjArchitecture, ObjInfo, ObjKind, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjArchitecture, ObjInfo, ObjKind, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet,
ObjSymbolFlags, ObjSymbolKind, ObjSymbolFlags, ObjSymbolKind, SectionIndex,
}, },
util::{ util::{
alf::{AlfFile, AlfSymbol, ALF_MAGIC}, alf::{AlfFile, AlfSymbol, ALF_MAGIC},
@ -75,7 +75,7 @@ pub struct DolSection {
pub size: u32, pub size: u32,
pub kind: DolSectionKind, pub kind: DolSectionKind,
// TODO remove // TODO remove
pub index: usize, pub index: SectionIndex,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -103,7 +103,7 @@ impl FromReader for DolFile {
data_size: size, data_size: size,
size, size,
kind: DolSectionKind::Text, kind: DolSectionKind::Text,
index: sections.len(), index: sections.len() as SectionIndex,
}); });
} }
for (idx, &size) in header.data_sizes.iter().enumerate() { for (idx, &size) in header.data_sizes.iter().enumerate() {
@ -116,7 +116,7 @@ impl FromReader for DolFile {
data_size: size, data_size: size,
size, size,
kind: DolSectionKind::Data, kind: DolSectionKind::Data,
index: sections.len(), index: sections.len() as SectionIndex,
}); });
} }
sections.push(DolSection { sections.push(DolSection {
@ -125,7 +125,7 @@ impl FromReader for DolFile {
data_size: 0, data_size: 0,
size: header.bss_size, size: header.bss_size,
kind: DolSectionKind::Bss, kind: DolSectionKind::Bss,
index: sections.len(), index: sections.len() as SectionIndex,
}); });
Ok(Self { header, sections }) Ok(Self { header, sections })
} }
@ -286,8 +286,8 @@ pub fn process_dol(buf: &[u8], name: &str) -> Result<ObjInfo> {
dol.sections().iter().filter(|section| section.kind == DolSectionKind::Text).count(); dol.sections().iter().filter(|section| section.kind == DolSectionKind::Text).count();
let mut eti_entries: Vec<EtiEntry> = Vec::new(); let mut eti_entries: Vec<EtiEntry> = Vec::new();
let mut eti_init_info_range: Option<(u32, u32)> = None; let mut eti_init_info_range: Option<(u32, u32)> = None;
let mut extab_section: Option<usize> = None; let mut extab_section: Option<SectionIndex> = None;
let mut extabindex_section: Option<usize> = None; let mut extabindex_section: Option<SectionIndex> = None;
'outer: for dol_section in 'outer: for dol_section in
dol.sections().iter().filter(|section| section.kind == DolSectionKind::Data) dol.sections().iter().filter(|section| section.kind == DolSectionKind::Data)
{ {
@ -537,8 +537,9 @@ pub fn process_dol(buf: &[u8], name: &str) -> Result<ObjInfo> {
} }
// Apply section indices // Apply section indices
let mut init_section_index = None; let mut init_section_index: Option<SectionIndex> = None;
for (idx, section) in sections.iter_mut().enumerate() { for (idx, section) in sections.iter_mut().enumerate() {
let idx = idx as SectionIndex;
match section.name.as_str() { match section.name.as_str() {
".init" => { ".init" => {
init_section_index = Some(idx); init_section_index = Some(idx);

View File

@ -26,6 +26,7 @@ use crate::{
obj::{ obj::{
ObjArchitecture, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind, ObjArchitecture, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind,
ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjUnit, ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjUnit,
SectionIndex as ObjSectionIndex, SymbolIndex as ObjSymbolIndex,
}, },
util::{ util::{
comment::{CommentSym, MWComment}, comment::{CommentSym, MWComment},
@ -97,7 +98,7 @@ where P: AsRef<Path> {
size: section.size(), size: section.size(),
data: section.uncompressed_data()?.to_vec(), data: section.uncompressed_data()?.to_vec(),
align: section.align(), align: section.align(),
elf_index: section.index().0, elf_index: section.index().0 as ObjSectionIndex,
relocations: Default::default(), relocations: Default::default(),
virtual_address: None, // Loaded from section symbol virtual_address: None, // Loaded from section symbol
file_offset: section.file_range().map(|(v, _)| v).unwrap_or_default(), file_offset: section.file_range().map(|(v, _)| v).unwrap_or_default(),
@ -151,7 +152,7 @@ where P: AsRef<Path> {
}; };
let mut symbols: Vec<ObjSymbol> = vec![]; let mut symbols: Vec<ObjSymbol> = vec![];
let mut symbol_indexes: Vec<Option<usize>> = vec![None /* ELF null symbol */]; let mut symbol_indexes: Vec<Option<ObjSymbolIndex>> = vec![None /* ELF null symbol */];
let mut section_starts = IndexMap::<String, Vec<(u64, String)>>::new(); let mut section_starts = IndexMap::<String, Vec<(u64, String)>>::new();
let mut name_to_index = HashMap::<String, usize>::new(); // for resolving duplicate names let mut name_to_index = HashMap::<String, usize>::new(); // for resolving duplicate names
let mut boundary_state = BoundaryState::LookForFile(Default::default()); let mut boundary_state = BoundaryState::LookForFile(Default::default());
@ -307,7 +308,7 @@ where P: AsRef<Path> {
symbol_indexes.push(None); symbol_indexes.push(None);
continue; continue;
} }
symbol_indexes.push(Some(symbols.len())); symbol_indexes.push(Some(symbols.len() as ObjSymbolIndex));
let align = mw_comment.as_ref().map(|(_, vec)| vec[symbol.index().0].align); let align = mw_comment.as_ref().map(|(_, vec)| vec[symbol.index().0].align);
symbols.push(to_obj_symbol(&obj_file, &symbol, &section_indexes, align)?); symbols.push(to_obj_symbol(&obj_file, &symbol, &section_indexes, align)?);
} }
@ -401,7 +402,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
} }
writer.reserve_null_section_index(); writer.reserve_null_section_index();
let mut out_sections: Vec<OutSection> = Vec::with_capacity(obj.sections.len()); let mut out_sections: Vec<OutSection> = Vec::with_capacity(obj.sections.len() as usize);
for (_, section) in obj.sections.iter() { for (_, section) in obj.sections.iter() {
let name = writer.add_section_name(section.name.as_bytes()); let name = writer.add_section_name(section.name.as_bytes());
let index = writer.reserve_section_index(); let index = writer.reserve_section_index();
@ -416,7 +417,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
}); });
} }
let mut rela_names: Vec<String> = vec![Default::default(); obj.sections.len()]; let mut rela_names: Vec<String> = vec![Default::default(); obj.sections.len() as usize];
for (((_, section), out_section), rela_name) in for (((_, section), out_section), rela_name) in
obj.sections.iter().zip(&mut out_sections).zip(&mut rela_names) obj.sections.iter().zip(&mut out_sections).zip(&mut rela_names)
{ {
@ -449,7 +450,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
}); });
// Generate .comment data // Generate .comment data
let mut comment_data = Vec::<u8>::with_capacity(0x2C + obj.symbols.count() * 8); let mut comment_data = Vec::<u8>::with_capacity(0x2C + obj.symbols.count() as usize * 8);
mw_comment.to_writer_static(&mut comment_data, Endian::Big)?; mw_comment.to_writer_static(&mut comment_data, Endian::Big)?;
// Null symbol // Null symbol
CommentSym { align: 0, vis_flags: 0, active_flags: 0 } CommentSym { align: 0, vis_flags: 0, active_flags: 0 }
@ -485,8 +486,8 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
None None
}; };
let mut out_symbols: Vec<OutSymbol> = Vec::with_capacity(obj.symbols.count()); let mut out_symbols: Vec<OutSymbol> = Vec::with_capacity(obj.symbols.count() as usize);
let mut symbol_map = vec![None; obj.symbols.count()]; let mut symbol_map = vec![None; obj.symbols.count() as usize];
let mut section_symbol_offset = 0; let mut section_symbol_offset = 0;
let mut num_local = 0; let mut num_local = 0;
@ -532,7 +533,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
// Add section symbols for relocatable objects // Add section symbols for relocatable objects
if obj.kind == ObjKind::Relocatable { if obj.kind == ObjKind::Relocatable {
for (section_index, section) in obj.sections.iter() { for (section_index, section) in obj.sections.iter() {
let out_section_index = out_sections.get(section_index).map(|s| s.index); let out_section_index = out_sections.get(section_index as usize).map(|s| s.index);
let index = writer.reserve_symbol_index(out_section_index); let index = writer.reserve_symbol_index(out_section_index);
let sym = object::write::elf::Sym { let sym = object::write::elf::Sym {
name: None, name: None,
@ -561,19 +562,19 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
for (symbol_index, symbol) in obj for (symbol_index, symbol) in obj
.symbols .symbols
.iter() .iter()
.enumerate()
.filter(|&(_, s)| s.flags.is_local()) .filter(|&(_, s)| s.flags.is_local())
.chain(obj.symbols.iter().enumerate().filter(|&(_, s)| !s.flags.is_local())) .chain(obj.symbols.iter().filter(|&(_, s)| !s.flags.is_local()))
{ {
if obj.kind == ObjKind::Relocatable && symbol.kind == ObjSymbolKind::Section { if obj.kind == ObjKind::Relocatable && symbol.kind == ObjSymbolKind::Section {
// We wrote section symbols above, so skip them here // We wrote section symbols above, so skip them here
let section_index = let section_index =
symbol.section.ok_or_else(|| anyhow!("section symbol without section index"))?; symbol.section.ok_or_else(|| anyhow!("section symbol without section index"))?;
symbol_map[symbol_index] = Some(section_symbol_offset + section_index as u32); symbol_map[symbol_index as usize] =
Some(section_symbol_offset as ObjSectionIndex + section_index);
continue; continue;
} }
let section = symbol.section.and_then(|idx| out_sections.get(idx)); let section = symbol.section.and_then(|idx| out_sections.get(idx as usize));
let section_index = section.map(|s| s.index); let section_index = section.map(|s| s.index);
let index = writer.reserve_symbol_index(section_index); let index = writer.reserve_symbol_index(section_index);
let name_index = if symbol.name.is_empty() { let name_index = if symbol.name.is_empty() {
@ -617,7 +618,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
num_local = writer.symbol_count(); num_local = writer.symbol_count();
} }
out_symbols.push(OutSymbol { index, sym }); out_symbols.push(OutSymbol { index, sym });
symbol_map[symbol_index] = Some(index.0); symbol_map[symbol_index as usize] = Some(index.0);
if let Some((comment_data, _)) = &mut comment_data { if let Some((comment_data, _)) = &mut comment_data {
CommentSym::from(symbol, export_all).to_writer_static(comment_data, Endian::Big)?; CommentSym::from(symbol, export_all).to_writer_static(comment_data, Endian::Big)?;
} }
@ -635,7 +636,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
writer.reserve_file_header(); writer.reserve_file_header();
if obj.kind == ObjKind::Executable { if obj.kind == ObjKind::Executable {
writer.reserve_program_headers(obj.sections.len() as u32); writer.reserve_program_headers(obj.sections.len());
} }
for ((_, section), out_section) in obj.sections.iter().zip(&mut out_sections) { for ((_, section), out_section) in obj.sections.iter().zip(&mut out_sections) {
@ -734,7 +735,7 @@ pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
ensure!(writer.len() == out_section.rela_offset); ensure!(writer.len() == out_section.rela_offset);
for (addr, reloc) in section.relocations.iter() { for (addr, reloc) in section.relocations.iter() {
let (r_offset, r_type) = reloc.to_elf(addr); let (r_offset, r_type) = reloc.to_elf(addr);
let r_sym = symbol_map[reloc.target_symbol] let r_sym = symbol_map[reloc.target_symbol as usize]
.ok_or_else(|| anyhow!("Relocation against stripped symbol"))?; .ok_or_else(|| anyhow!("Relocation against stripped symbol"))?;
writer.write_relocation(true, &Rel { r_offset, r_sym, r_type, r_addend: reloc.addend }); writer.write_relocation(true, &Rel { r_offset, r_sym, r_type, r_addend: reloc.addend });
} }
@ -893,7 +894,7 @@ fn to_obj_symbol(
name: name.to_string(), name: name.to_string(),
demangled_name: demangle(name, &Default::default()), demangled_name: demangle(name, &Default::default()),
address: symbol.address(), address: symbol.address(),
section: section_idx, section: section_idx.map(|s| s as ObjSectionIndex),
size: symbol.size(), size: symbol.size(),
size_known: true, size_known: true,
flags, flags,
@ -927,7 +928,7 @@ pub fn to_obj_reloc_kind(flags: RelocationFlags) -> Result<ObjRelocKind> {
fn to_obj_reloc( fn to_obj_reloc(
obj_file: &object::File<'_>, obj_file: &object::File<'_>,
symbol_indexes: &[Option<usize>], symbol_indexes: &[Option<ObjSymbolIndex>],
section_data: &[u8], section_data: &[u8],
address: u64, address: u64,
reloc: Relocation, reloc: Relocation,

View File

@ -37,7 +37,7 @@ pub fn generate_ldscript(
} }
let mut force_active = force_active.to_vec(); let mut force_active = force_active.to_vec();
for symbol in obj.symbols.iter() { for (_, symbol) in obj.symbols.iter() {
if symbol.flags.is_exported() && symbol.flags.is_global() && !symbol.flags.is_no_write() { if symbol.flags.is_exported() && symbol.flags.is_global() && !symbol.flags.is_no_write() {
force_active.push(symbol.name.clone()); force_active.push(symbol.name.clone());
} }
@ -86,7 +86,7 @@ pub fn generate_ldscript_partial(
} }
let mut force_active = force_active.to_vec(); let mut force_active = force_active.to_vec();
for symbol in obj.symbols.iter() { for (_, symbol) in obj.symbols.iter() {
if symbol.flags.is_exported() && symbol.flags.is_global() && !symbol.flags.is_no_write() { if symbol.flags.is_exported() && symbol.flags.is_global() && !symbol.flags.is_no_write() {
force_active.push(symbol.name.clone()); force_active.push(symbol.name.clone());
} }

View File

@ -21,7 +21,7 @@ use crate::{
obj::{ obj::{
section_kind_for_section, ObjArchitecture, ObjInfo, ObjKind, ObjSection, ObjSectionKind, section_kind_for_section, ObjArchitecture, ObjInfo, ObjKind, ObjSection, ObjSectionKind,
ObjSections, ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSections, ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind,
ObjSymbols, ObjUnit, ObjSymbols, ObjUnit, SectionIndex,
}, },
util::nested::NestedVec, util::nested::NestedVec,
vfs::open_file, vfs::open_file,
@ -770,7 +770,7 @@ pub fn apply_map(mut result: MapInfo, obj: &mut ObjInfo) -> Result<()> {
&& (s.address + s.size) <= (section.address + section.size) as u32 && (s.address + s.size) <= (section.address + section.size) as u32
}) })
} else { } else {
result.sections.iter().filter(|s| s.size > 0).nth(section_index) result.sections.iter().filter(|s| s.size > 0).nth(section_index as usize)
}; };
if let Some(info) = opt { if let Some(info) = opt {
if section.section_known && section.name != info.name { if section.section_known && section.name != info.name {
@ -814,7 +814,7 @@ pub fn apply_map(mut result: MapInfo, obj: &mut ObjInfo) -> Result<()> {
".data" ".data"
} }
} else if let Some(section_name) = } else if let Some(section_name) =
DEFAULT_REL_SECTIONS.get(section.elf_index) DEFAULT_REL_SECTIONS.get(section.elf_index as usize)
{ {
section_name section_name
} else { } else {
@ -1014,7 +1014,7 @@ pub fn create_obj(result: &MapInfo) -> Result<ObjInfo> {
fn add_symbol( fn add_symbol(
obj: &mut ObjInfo, obj: &mut ObjInfo,
symbol_entry: &SymbolEntry, symbol_entry: &SymbolEntry,
section: Option<usize>, section: Option<SectionIndex>,
ignore_alignment: bool, ignore_alignment: bool,
) -> Result<()> { ) -> Result<()> {
let demangled_name = demangle(&symbol_entry.name, &DemangleOptions::default()); let demangled_name = demangle(&symbol_entry.name, &DemangleOptions::default());

View File

@ -13,7 +13,7 @@ use crate::{
array_ref_mut, array_ref_mut,
obj::{ obj::{
ObjArchitecture, ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol, ObjArchitecture, ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbol,
ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, SectionIndex,
}, },
util::{ util::{
align_up, align_up,
@ -418,7 +418,7 @@ where R: Read + Seek + ?Sized {
_ => None, // determined later _ => None, // determined later
} }
.unwrap_or_default() as u64, .unwrap_or_default() as u64,
elf_index: idx, elf_index: idx as SectionIndex,
relocations: Default::default(), relocations: Default::default(),
virtual_address: None, // TODO option to set? virtual_address: None, // TODO option to set?
file_offset: offset as u64, file_offset: offset as u64,
@ -440,7 +440,7 @@ where R: Read + Seek + ?Sized {
let (section_index, _) = sections let (section_index, _) = sections
.iter() .iter()
.enumerate() .enumerate()
.find(|&(_, section)| section.elf_index == rel_section_idx as usize) .find(|&(_, section)| section.elf_index == rel_section_idx as SectionIndex)
.ok_or_else(|| anyhow!("Failed to locate {name} section {rel_section_idx}"))?; .ok_or_else(|| anyhow!("Failed to locate {name} section {rel_section_idx}"))?;
log::debug!("Adding {name} section {rel_section_idx} offset {offset:#X}"); log::debug!("Adding {name} section {rel_section_idx} offset {offset:#X}");
let mut flags = ObjSymbolFlagSet(ObjSymbolFlags::Global.into()); let mut flags = ObjSymbolFlagSet(ObjSymbolFlags::Global.into());
@ -450,7 +450,7 @@ where R: Read + Seek + ?Sized {
symbols.push(ObjSymbol { symbols.push(ObjSymbol {
name: name.to_string(), name: name.to_string(),
address: offset as u64, address: offset as u64,
section: Some(section_index), section: Some(section_index as SectionIndex),
flags, flags,
kind: ObjSymbolKind::Function, kind: ObjSymbolKind::Function,
..Default::default() ..Default::default()

View File

@ -9,7 +9,7 @@ use cwdemangle::{demangle, DemangleOptions};
use crate::{ use crate::{
obj::{ obj::{
ObjArchitecture, ObjInfo, ObjKind, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjArchitecture, ObjInfo, ObjKind, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet,
ObjSymbolFlags, ObjSymbolKind, ObjSymbolFlags, ObjSymbolKind, SectionIndex,
}, },
util::{ util::{
file::{read_c_string, read_string}, file::{read_c_string, read_string},
@ -452,7 +452,7 @@ where R: Read + Seek + ?Sized {
size: size as u64, size: size as u64,
data, data,
align: 0, align: 0,
elf_index: idx as usize, elf_index: idx as SectionIndex,
relocations: Default::default(), relocations: Default::default(),
virtual_address: None, // TODO option to set? virtual_address: None, // TODO option to set?
file_offset: offset as u64, file_offset: offset as u64,
@ -476,13 +476,13 @@ where R: Read + Seek + ?Sized {
let (section_index, _) = sections let (section_index, _) = sections
.iter() .iter()
.enumerate() .enumerate()
.find(|&(_, section)| section.elf_index == rel_section_idx as usize) .find(|&(_, section)| section.elf_index == rel_section_idx as SectionIndex)
.ok_or_else(|| anyhow!("Failed to locate {name} section {rel_section_idx}"))?; .ok_or_else(|| anyhow!("Failed to locate {name} section {rel_section_idx}"))?;
log::debug!("Adding {name} section {rel_section_idx} offset {offset:#X}"); log::debug!("Adding {name} section {rel_section_idx} offset {offset:#X}");
symbols.push(ObjSymbol { symbols.push(ObjSymbol {
name: name.to_string(), name: name.to_string(),
address: offset as u64, address: offset as u64,
section: Some(section_index), section: Some(section_index as SectionIndex),
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()), flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
kind: ObjSymbolKind::Function, kind: ObjSymbolKind::Function,
..Default::default() ..Default::default()
@ -526,7 +526,7 @@ where R: Read + Seek + ?Sized {
let section = sections let section = sections
.iter() .iter()
.enumerate() .enumerate()
.find(|&(_, section)| section.elf_index == symbol.section_index as usize) .find(|&(_, section)| section.elf_index == symbol.section_index as SectionIndex)
.map(|(idx, _)| idx) .map(|(idx, _)| idx)
// HACK: selfiles won't have any sections // HACK: selfiles won't have any sections
.unwrap_or(symbol.section_index as usize); .unwrap_or(symbol.section_index as usize);
@ -541,7 +541,7 @@ where R: Read + Seek + ?Sized {
name, name,
demangled_name, demangled_name,
address: symbol.offset as u64, address: symbol.offset as u64,
section: Some(section), section: Some(section as SectionIndex),
..Default::default() ..Default::default()
}); });
} }

View File

@ -18,7 +18,7 @@ use crate::{
array_ref, array_ref,
obj::{ obj::{
ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSymbol, ObjSymbolFlagSet, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSymbol, ObjSymbolFlagSet,
ObjSymbolKind, ObjSymbolKind, SectionIndex, SymbolIndex,
}, },
util::elf::process_elf, util::elf::process_elf,
}; };
@ -36,13 +36,13 @@ pub struct OutSymbol {
pub struct OutReloc { pub struct OutReloc {
pub offset: u32, pub offset: u32,
pub kind: ObjRelocKind, pub kind: ObjRelocKind,
pub symbol: usize, pub symbol: u32,
pub addend: i32, pub addend: i32,
} }
#[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
pub struct FunctionSignature { pub struct FunctionSignature {
pub symbol: usize, pub symbol: u32,
pub hash: String, pub hash: String,
pub signature: String, pub signature: String,
pub symbols: Vec<OutSymbol>, pub symbols: Vec<OutSymbol>,
@ -92,12 +92,12 @@ pub fn check_signatures(
let mut name = None; let mut name = None;
for signature in signatures { for signature in signatures {
if name.is_none() { if name.is_none() {
name = Some(signature.symbols[signature.symbol].name.clone()); name = Some(signature.symbols[signature.symbol as usize].name.clone());
} }
if check_signature(data, signature)? { if check_signature(data, signature)? {
log::debug!( log::debug!(
"Found {} @ {:#010X} (hash {})", "Found {} @ {:#010X} (hash {})",
signature.symbols[signature.symbol].name, signature.symbols[signature.symbol as usize].name,
addr, addr,
signature.hash signature.hash
); );
@ -114,9 +114,9 @@ pub fn apply_symbol(
obj: &mut ObjInfo, obj: &mut ObjInfo,
target: SectionAddress, target: SectionAddress,
sig_symbol: &OutSymbol, sig_symbol: &OutSymbol,
) -> Result<usize> { ) -> Result<SymbolIndex> {
let mut target_section_index = let mut target_section_index =
if target.section == usize::MAX { None } else { Some(target.section) }; if target.section == SectionIndex::MAX { None } else { Some(target.section) };
if let Some(target_section_index) = target_section_index { if let Some(target_section_index) = target_section_index {
let target_section = &mut obj.sections[target_section_index]; let target_section = &mut obj.sections[target_section_index];
if !target_section.section_known { if !target_section.section_known {
@ -154,7 +154,7 @@ pub fn apply_signature(
addr: SectionAddress, addr: SectionAddress,
signature: &FunctionSignature, signature: &FunctionSignature,
) -> Result<()> { ) -> Result<()> {
let in_symbol = &signature.symbols[signature.symbol]; let in_symbol = &signature.symbols[signature.symbol as usize];
let symbol_idx = apply_symbol(obj, addr, in_symbol)?; let symbol_idx = apply_symbol(obj, addr, in_symbol)?;
let mut tracker = Tracker::new(obj); let mut tracker = Tracker::new(obj);
for reloc in &signature.relocations { for reloc in &signature.relocations {
@ -185,7 +185,7 @@ pub fn apply_signature(
} }
_ => bail!("Relocation mismatch: {:?} != {:?}", reloc, sig_reloc.kind), _ => bail!("Relocation mismatch: {:?} != {:?}", reloc, sig_reloc.kind),
}; };
let sig_symbol = &signature.symbols[sig_reloc.symbol]; let sig_symbol = &signature.symbols[sig_reloc.symbol as usize];
// log::info!("Processing relocation {:#010X} {:?} -> {:#010X} {:?}", reloc_addr, reloc, target, sig_symbol); // log::info!("Processing relocation {:#010X} {:?} -> {:#010X} {:?}", reloc_addr, reloc, target, sig_symbol);
let target_symbol_idx = apply_symbol(obj, target, sig_symbol)?; let target_symbol_idx = apply_symbol(obj, target, sig_symbol)?;
let obj_reloc = ObjReloc { let obj_reloc = ObjReloc {
@ -200,7 +200,7 @@ pub fn apply_signature(
for reloc in &signature.relocations { for reloc in &signature.relocations {
let addr = addr + reloc.offset; let addr = addr + reloc.offset;
if !tracker.relocations.contains_key(&addr) { if !tracker.relocations.contains_key(&addr) {
let sig_symbol = &signature.symbols[reloc.symbol]; let sig_symbol = &signature.symbols[reloc.symbol as usize];
bail!("Missing relocation @ {:#010X}: {:?} -> {:?}", addr, reloc, sig_symbol); bail!("Missing relocation @ {:#010X}: {:?} -> {:?}", addr, reloc, sig_symbol);
} }
} }
@ -250,7 +250,7 @@ pub fn generate_signature<P>(path: P, symbol_name: &str) -> Result<Option<Functi
where P: AsRef<Path> { where P: AsRef<Path> {
let mut out_symbols: Vec<OutSymbol> = Vec::new(); let mut out_symbols: Vec<OutSymbol> = Vec::new();
let mut out_relocs: Vec<OutReloc> = Vec::new(); let mut out_relocs: Vec<OutReloc> = Vec::new();
let mut symbol_map: BTreeMap<usize, usize> = BTreeMap::new(); let mut symbol_map: BTreeMap<SymbolIndex, u32> = BTreeMap::new();
let mut obj = process_elf(path)?; let mut obj = process_elf(path)?;
if obj.kind == ObjKind::Executable if obj.kind == ObjKind::Executable
@ -312,7 +312,7 @@ where P: AsRef<Path> {
let symbol_idx = match symbol_map.entry(reloc.target_symbol) { let symbol_idx = match symbol_map.entry(reloc.target_symbol) {
btree_map::Entry::Vacant(e) => { btree_map::Entry::Vacant(e) => {
let target = &obj.symbols[reloc.target_symbol]; let target = &obj.symbols[reloc.target_symbol];
let symbol_idx = out_symbols.len(); let symbol_idx = out_symbols.len() as u32;
e.insert(symbol_idx); e.insert(symbol_idx);
out_symbols.push(OutSymbol { out_symbols.push(OutSymbol {
kind: target.kind, kind: target.kind,

View File

@ -15,7 +15,7 @@ use crate::{
obj::{ obj::{
ObjArchitecture, ObjInfo, ObjKind, ObjReloc, ObjRelocations, ObjSection, ObjSectionKind, ObjArchitecture, ObjInfo, ObjKind, ObjReloc, ObjRelocations, ObjSection, ObjSectionKind,
ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, ObjSplit, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope,
ObjUnit, ObjUnit, SectionIndex, SymbolIndex,
}, },
util::{align_up, comment::MWComment}, util::{align_up, comment::MWComment},
}; };
@ -444,8 +444,8 @@ fn create_gap_splits(obj: &mut ObjInfo) -> Result<()> {
/// Ensures that all .bss splits following a common split are also marked as common. /// Ensures that all .bss splits following a common split are also marked as common.
fn update_common_splits(obj: &mut ObjInfo, common_start: Option<u32>) -> Result<()> { fn update_common_splits(obj: &mut ObjInfo, common_start: Option<u32>) -> Result<()> {
let Some((bss_section_index, common_bss_start)) = (match common_start { let Some(common_bss_start) = (match common_start {
Some(addr) => Some(( Some(addr) => Some(SectionAddress::new(
obj.sections.by_name(".bss")?.ok_or_else(|| anyhow!("Failed to find .bss section"))?.0, obj.sections.by_name(".bss")?.ok_or_else(|| anyhow!("Failed to find .bss section"))?.0,
addr, addr,
)), )),
@ -454,8 +454,8 @@ fn update_common_splits(obj: &mut ObjInfo, common_start: Option<u32>) -> Result<
return Ok(()); return Ok(());
}; };
log::debug!("Found common BSS start at {:#010X}", common_bss_start); log::debug!("Found common BSS start at {:#010X}", common_bss_start);
let bss_section = &mut obj.sections[bss_section_index]; let bss_section = &mut obj.sections[common_bss_start.section];
for (addr, split) in bss_section.splits.for_range_mut(common_bss_start..) { for (addr, split) in bss_section.splits.for_range_mut(common_bss_start.address..) {
if !split.common { if !split.common {
split.common = true; split.common = true;
log::debug!("Added common flag to split {} at {:#010X}", split.unit, addr); log::debug!("Added common flag to split {} at {:#010X}", split.unit, addr);
@ -593,8 +593,8 @@ fn add_padding_symbols(obj: &mut ObjInfo) -> Result<()> {
.peekable(); .peekable();
while let Some((_, symbol)) = iter.next() { while let Some((_, symbol)) = iter.next() {
// Common BSS is allowed to have gaps and overlaps to accurately match the common BSS inflation bug // Common BSS is allowed to have gaps and overlaps to accurately match the common BSS inflation bug
if matches!(common_bss, Some((idx, addr)) if if matches!(common_bss, Some(addr) if
section_index == idx && symbol.address as u32 >= addr) section_index == addr.section && symbol.address as u32 >= addr.address)
{ {
continue; continue;
} }
@ -933,11 +933,11 @@ fn resolve_link_order(obj: &ObjInfo) -> Result<Vec<ObjUnit>> {
#[instrument(level = "debug", skip(obj))] #[instrument(level = "debug", skip(obj))]
pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo>> { pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo>> {
let mut objects: Vec<ObjInfo> = vec![]; let mut objects: Vec<ObjInfo> = vec![];
let mut object_symbols: Vec<Vec<Option<usize>>> = vec![]; let mut object_symbols: Vec<Vec<Option<SymbolIndex>>> = vec![];
let mut name_to_obj: HashMap<String, usize> = HashMap::new(); let mut name_to_obj: HashMap<String, usize> = HashMap::new();
for unit in &obj.link_order { for unit in &obj.link_order {
name_to_obj.insert(unit.name.clone(), objects.len()); name_to_obj.insert(unit.name.clone(), objects.len());
object_symbols.push(vec![None; obj.symbols.count()]); object_symbols.push(vec![None; obj.symbols.count() as usize]);
let mut split_obj = ObjInfo::new( let mut split_obj = ObjInfo::new(
ObjKind::Relocatable, ObjKind::Relocatable,
ObjArchitecture::PowerPc, ObjArchitecture::PowerPc,
@ -1079,7 +1079,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
s.section == Some(section_index) && !is_linker_generated_label(&s.name) s.section == Some(section_index) && !is_linker_generated_label(&s.name)
}) })
{ {
if symbol_idxs[symbol_idx].is_some() { if symbol_idxs[symbol_idx as usize].is_some() {
continue; // should never happen? continue; // should never happen?
} }
@ -1092,7 +1092,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
continue; continue;
} }
symbol_idxs[symbol_idx] = Some(split_obj.symbols.add_direct(ObjSymbol { let new_index = split_obj.symbols.add_direct(ObjSymbol {
name: symbol.name.clone(), name: symbol.name.clone(),
demangled_name: symbol.demangled_name.clone(), demangled_name: symbol.demangled_name.clone(),
address: if split.common { address: if split.common {
@ -1113,7 +1113,8 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
data_kind: symbol.data_kind, data_kind: symbol.data_kind,
name_hash: symbol.name_hash, name_hash: symbol.name_hash,
demangled_name_hash: symbol.demangled_name_hash, demangled_name_hash: symbol.demangled_name_hash,
})?); })?;
symbol_idxs[symbol_idx as usize] = Some(new_index);
} }
// For mwldeppc 2.7 and above, a .comment section is required to link without error // For mwldeppc 2.7 and above, a .comment section is required to link without error
@ -1156,7 +1157,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
let symbol_idxs = &mut object_symbols[obj_idx]; let symbol_idxs = &mut object_symbols[obj_idx];
for (_section_index, section) in out_obj.sections.iter_mut() { for (_section_index, section) in out_obj.sections.iter_mut() {
for (reloc_address, reloc) in section.relocations.iter_mut() { for (reloc_address, reloc) in section.relocations.iter_mut() {
match symbol_idxs[reloc.target_symbol] { match symbol_idxs[reloc.target_symbol as usize] {
Some(out_sym_idx) => { Some(out_sym_idx) => {
reloc.target_symbol = out_sym_idx; reloc.target_symbol = out_sym_idx;
} }
@ -1189,7 +1190,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
globalize_symbols.push((reloc.target_symbol, new_name)); globalize_symbols.push((reloc.target_symbol, new_name));
} }
symbol_idxs[reloc.target_symbol] = Some(out_sym_idx); symbol_idxs[reloc.target_symbol as usize] = Some(out_sym_idx);
out_obj.symbols.add_direct(ObjSymbol { out_obj.symbols.add_direct(ObjSymbol {
name: target_sym.name.clone(), name: target_sym.name.clone(),
demangled_name: target_sym.demangled_name.clone(), demangled_name: target_sym.demangled_name.clone(),
@ -1233,7 +1234,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
// Upgrade local symbols to global if necessary // Upgrade local symbols to global if necessary
for (obj, symbol_map) in objects.iter_mut().zip(&object_symbols) { for (obj, symbol_map) in objects.iter_mut().zip(&object_symbols) {
for (globalize_idx, new_name) in &globalize_symbols { for (globalize_idx, new_name) in &globalize_symbols {
if let Some(symbol_idx) = symbol_map[*globalize_idx] { if let Some(symbol_idx) = symbol_map[*globalize_idx as usize] {
let mut symbol = obj.symbols[symbol_idx].clone(); let mut symbol = obj.symbols[symbol_idx].clone();
symbol.name.clone_from(new_name); symbol.name.clone_from(new_name);
if symbol.flags.is_local() { if symbol.flags.is_local() {
@ -1248,7 +1249,7 @@ pub fn split_obj(obj: &ObjInfo, module_name: Option<&str>) -> Result<Vec<ObjInfo
// Extern linker generated symbols // Extern linker generated symbols
for obj in &mut objects { for obj in &mut objects {
let mut replace_symbols = vec![]; let mut replace_symbols = vec![];
for (symbol_idx, symbol) in obj.symbols.iter().enumerate() { for (symbol_idx, symbol) in obj.symbols.iter() {
if is_linker_generated_label(&symbol.name) && symbol.section.is_some() { if is_linker_generated_label(&symbol.name) && symbol.section.is_some() {
log::debug!("Externing {:?} in {}", symbol, obj.name); log::debug!("Externing {:?} in {}", symbol, obj.name);
replace_symbols.push((symbol_idx, ObjSymbol { replace_symbols.push((symbol_idx, ObjSymbol {
@ -1352,7 +1353,7 @@ pub fn is_linker_generated_object(name: &str) -> bool {
} }
/// Locate the end address of a section when excluding linker generated objects /// Locate the end address of a section when excluding linker generated objects
pub fn end_for_section(obj: &ObjInfo, section_index: usize) -> Result<SectionAddress> { pub fn end_for_section(obj: &ObjInfo, section_index: SectionIndex) -> Result<SectionAddress> {
let section = obj let section = obj
.sections .sections
.get(section_index) .get(section_index)