Skip to content

Commit

Permalink
Migrate SectionIndex/SymbolIndex to u32
Browse files Browse the repository at this point in the history
This halves the size of structs like SectionAddress.
  • Loading branch information
encounter committed Oct 5, 2024
1 parent 1f4b452 commit b184fee
Show file tree
Hide file tree
Showing 24 changed files with 262 additions and 214 deletions.
11 changes: 7 additions & 4 deletions src/analysis/cfa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ use crate::{
vm::{BranchTarget, GprValue, StepResult, VM},
RelocationTarget,
},
obj::{ObjInfo, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind},
obj::{
ObjInfo, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind,
SectionIndex,
},
};

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct SectionAddress {
pub section: usize,
pub section: SectionIndex,
pub address: u32,
}

Expand All @@ -38,7 +41,7 @@ impl Display for 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 {
Self { section: self.section, address: self.address.wrapping_add_signed(offset) }
Expand Down Expand Up @@ -116,7 +119,7 @@ pub struct AnalyzerState {
pub functions: BTreeMap<SectionAddress, FunctionInfo>,
pub jump_tables: BTreeMap<SectionAddress, u32>,
pub known_symbols: BTreeMap<SectionAddress, Vec<ObjSymbol>>,
pub known_sections: BTreeMap<usize, String>,
pub known_sections: BTreeMap<SectionIndex, String>,
}

impl AnalyzerState {
Expand Down
8 changes: 5 additions & 3 deletions src/analysis/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct VisitedAddresses {

impl VisitedAddresses {
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() {
if section.kind == ObjSectionKind::Code {
let size = (section.size / 4) as usize;
Expand All @@ -32,11 +32,13 @@ impl VisitedAddresses {
}

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) {
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]
Expand Down
14 changes: 7 additions & 7 deletions src/analysis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use ppc750cl::Ins;
use crate::{
analysis::cfa::SectionAddress,
array_ref,
obj::{ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbolKind},
obj::{
ObjInfo, ObjKind, ObjRelocKind, ObjSection, ObjSectionKind, ObjSymbolKind, SectionIndex,
},
};

pub mod cfa;
Expand Down Expand Up @@ -36,19 +38,17 @@ fn read_unresolved_relocation_address(
address: u32,
reloc_kind: Option<ObjRelocKind>,
) -> Result<Option<RelocationTarget>> {
if let Some(reloc) = obj
.unresolved_relocations
.iter()
.find(|reloc| reloc.section as usize == section.elf_index && reloc.address == address)
{
if let Some(reloc) = obj.unresolved_relocations.iter().find(|reloc| {
reloc.section as SectionIndex == section.elf_index && reloc.address == address
}) {
if reloc.module_id != obj.module_id {
return Ok(Some(RelocationTarget::External));
}
if let Some(reloc_kind) = reloc_kind {
ensure!(reloc.kind == reloc_kind);
}
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!(
"Failed to find target section {} for unresolved relocation",
reloc.target_section
Expand Down
4 changes: 2 additions & 2 deletions src/analysis/objects.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Result;

use crate::{
obj::{ObjDataKind, ObjInfo, ObjSectionKind, ObjSymbolKind},
obj::{ObjDataKind, ObjInfo, ObjSectionKind, ObjSymbolKind, SymbolIndex},
util::split::is_linker_generated_label,
};

Expand Down Expand Up @@ -64,7 +64,7 @@ pub fn detect_objects(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
.sections
.iter()
Expand Down
12 changes: 6 additions & 6 deletions src/analysis/pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
analysis::cfa::{AnalyzerState, FunctionInfo, SectionAddress},
obj::{
ObjInfo, ObjKind, ObjRelocKind, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet,
ObjSymbolFlags, ObjSymbolKind,
ObjSymbolFlags, ObjSymbolKind, SectionIndex,
},
};

Expand Down Expand Up @@ -147,14 +147,14 @@ impl AnalysisPass for FindRelCtorsDtors {
// And the section ends with a null pointer
while let Some(reloc) = obj.unresolved_relocations.iter().find(|reloc| {
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.kind == ObjRelocKind::Absolute
}) {
let Some((target_section_index, target_section)) = obj
.sections
.iter()
.find(|(_, section)| section.elf_index == reloc.target_section as usize)
let Some((target_section_index, target_section)) =
obj.sections.iter().find(|(_, section)| {
section.elf_index == reloc.target_section as SectionIndex
})
else {
return false;
};
Expand Down
22 changes: 11 additions & 11 deletions src/analysis/tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
},
obj::{
ObjDataKind, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSection, ObjSectionKind,
ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind,
ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, SectionIndex, SymbolIndex,
},
};

Expand Down Expand Up @@ -298,7 +298,7 @@ impl Tracker {
debug_assert_ne!(
value,
RelocationTarget::Address(SectionAddress::new(
usize::MAX,
SectionIndex::MAX,
0
))
);
Expand Down Expand Up @@ -359,7 +359,7 @@ impl Tracker {
debug_assert_ne!(
address,
RelocationTarget::Address(SectionAddress::new(
usize::MAX,
SectionIndex::MAX,
0
))
);
Expand All @@ -380,7 +380,7 @@ impl Tracker {
debug_assert_ne!(
address,
RelocationTarget::Address(SectionAddress::new(
usize::MAX,
SectionIndex::MAX,
0
))
);
Expand Down Expand Up @@ -464,7 +464,7 @@ impl Tracker {
{
(addr, is_function_addr(addr))
} else {
(SectionAddress::new(usize::MAX, 0), false)
(SectionAddress::new(SectionIndex::MAX, 0), false)
};
if branch.link || !is_fn_addr {
self.relocations.insert(ins_addr, match ins.op {
Expand Down Expand Up @@ -549,7 +549,7 @@ impl Tracker {
fn process_data(
&mut self,
obj: &ObjInfo,
section_index: usize,
section_index: SectionIndex,
section: &ObjSection,
) -> Result<()> {
let mut addr = SectionAddress::new(section_index, section.address as u32);
Expand Down Expand Up @@ -602,7 +602,7 @@ impl Tracker {
} else {
// Check known relocations (function signature matching)
if self.known_relocations.contains(&from) {
return Some(SectionAddress::new(usize::MAX, addr));
return Some(SectionAddress::new(SectionIndex::MAX, addr));
}
// Check special symbols
if self.stack_address == Some(addr)
Expand All @@ -613,7 +613,7 @@ impl Tracker {
|| self.sda2_base == Some(addr)
|| self.sda_base == Some(addr)
{
return Some(SectionAddress::new(usize::MAX, addr));
return Some(SectionAddress::new(SectionIndex::MAX, addr));
}
// Not valid
None
Expand All @@ -625,7 +625,7 @@ impl Tracker {
obj: &mut ObjInfo,
addr: u32,
reloc_kind: ObjRelocKind,
) -> Option<usize> {
) -> Option<SymbolIndex> {
if !matches!(
reloc_kind,
ObjRelocKind::PpcAddr16Ha | ObjRelocKind::PpcAddr16Lo
Expand All @@ -641,7 +641,7 @@ impl Tracker {
// 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 addr == value {
return generate_special_symbol(obj, value, name).ok();
Expand Down Expand Up @@ -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(
ObjSymbol {
name: name.to_string(),
Expand Down
44 changes: 24 additions & 20 deletions src/cmd/dol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::{
cmd::shasum::file_sha1_string,
obj::{
best_match_for_reloc, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSectionKind, ObjSymbol,
ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, SymbolIndex,
ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, SectionIndex, SymbolIndex,
},
util::{
asm::write_asm,
Expand Down Expand Up @@ -402,7 +402,7 @@ pub fn run(args: Args) -> Result<()> {

fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> {
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 {
Some(section) => section,
None => bail!(
Expand All @@ -411,15 +411,17 @@ fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> {
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)
} 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"
} else {
DOL_SECTION_NAMES.get(dol_section_index).and_then(|&opt| opt).ok_or_else(|| {
anyhow!("Can't add symbol for unknown DOL section {}", dol_section_index)
})?
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),
)?
};
let (dol_section_index, dol_section) = obj
.sections
Expand Down Expand Up @@ -577,7 +579,7 @@ fn update_symbols(
if source_module_id == obj.module_id {
// Skip if already resolved
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!(
"Failed to locate REL section {} in module ID {}: source module {}, {:?}",
rel_reloc.section,
Expand All @@ -591,8 +593,10 @@ fn update_symbols(
}
}

let (target_section_index, target_section) =
obj.sections.get_elf_index(rel_reloc.target_section as usize).ok_or_else(|| {
let (target_section_index, target_section) = obj
.sections
.get_elf_index(rel_reloc.target_section as SectionIndex)
.ok_or_else(|| {
anyhow!(
"Failed to locate REL section {} in module ID {}: source module {}, {:?}",
rel_reloc.target_section,
Expand Down Expand Up @@ -655,7 +659,7 @@ fn create_relocations(
for rel_reloc in take(&mut obj.unresolved_relocations) {
// Skip if already resolved
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!(
"Failed to locate REL section {} in module ID {}: {:?}",
rel_reloc.section,
Expand Down Expand Up @@ -683,7 +687,7 @@ fn create_relocations(
anyhow!("Failed to locate DOL section at {:#010X}", rel_reloc.addend)
})?
} 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!(
"Failed to locate module {} section {}",
Expand Down Expand Up @@ -720,7 +724,7 @@ fn create_relocations(
},
};
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)?;
}

Expand All @@ -739,7 +743,7 @@ fn resolve_external_relocations(
module_id: u32,
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 (_reloc_address, reloc) in section.relocations.iter_mut() {
Expand Down Expand Up @@ -1572,7 +1576,7 @@ fn diff(args: DiffArgs) -> Result<()> {
let linked_obj = process_elf(&args.elf_file)?;

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()
}) {
let Some(orig_section_index) = orig_sym.section else { continue };
Expand All @@ -1596,8 +1600,8 @@ fn diff(args: DiffArgs) -> Result<()> {
if linked_sym.size != orig_sym.size &&
// TODO validate common symbol sizes
// (need to account for inflation bug)
matches!(common_bss, Some((idx, addr)) if
orig_section_index == idx && orig_sym.address as u32 >= addr)
matches!(common_bss, Some(addr) if
orig_section_index == addr.section && orig_sym.address as u32 >= addr.address)
{
log::error!(
"Expected {} (type {:?}) to have size {:#X}, but found {:#X}",
Expand Down Expand Up @@ -1656,7 +1660,7 @@ fn diff(args: DiffArgs) -> Result<()> {
}

// 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)
}) {
let Some(orig_section_index) = orig_sym.section else { continue };
Expand Down Expand Up @@ -1756,7 +1760,7 @@ fn apply(args: ApplyArgs) -> Result<()> {
let linked_obj = process_elf(&args.elf_file)?;

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
if orig_sym.section.is_none() {
continue;
Expand Down Expand Up @@ -1832,7 +1836,7 @@ fn apply(args: ApplyArgs) -> Result<()> {
}

// 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)
|| is_auto_symbol(linked_sym)
|| is_linker_generated_object(&linked_sym.name)
Expand Down
Loading

0 comments on commit b184fee

Please sign in to comment.