Skip to content

Commit

Permalink
Support address in config symbol references
Browse files Browse the repository at this point in the history
Example: `symbol_name!.data:0x1234`
Allows disambiguating local symbols
with the same name.

Supported in `extract` and
`add_relocations` in config.yml

Resolves #58
  • Loading branch information
encounter committed Jun 4, 2024
1 parent 4701de3 commit 61cd72c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 7 deletions.
9 changes: 4 additions & 5 deletions src/cmd/dol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,11 +947,10 @@ fn split_write_obj(
let (_, symbol) = module
.obj
.symbols
.by_name(&extract.symbol)?
.by_ref(&module.obj.sections, &extract.symbol)?
.with_context(|| format!("Failed to locate symbol '{}'", extract.symbol))?;
let section_index = symbol
.section
.with_context(|| format!("Symbol '{}' has no section", extract.symbol))?;
let section_index =
symbol.section.with_context(|| format!("Symbol '{}' has no section", symbol.name))?;
let section = &module.obj.sections[section_index];
let data = section.symbol_data(symbol)?;

Expand Down Expand Up @@ -1893,7 +1892,7 @@ fn apply_block_relocations(
fn apply_add_relocations(obj: &mut ObjInfo, relocations: &[AddRelocationConfig]) -> Result<()> {
for reloc in relocations {
let SectionAddress { section, address } = reloc.source.resolve(obj)?;
let (target_symbol, _) = match obj.symbols.by_name(&reloc.target)? {
let (target_symbol, _) = match obj.symbols.by_ref(&obj.sections, &reloc.target)? {
Some(v) => v,
None => {
// Assume external symbol
Expand Down
38 changes: 36 additions & 2 deletions src/obj/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use serde_repr::{Deserialize_repr, Serialize_repr};

use crate::{
analysis::cfa::SectionAddress,
obj::{ObjKind, ObjRelocKind},
obj::{ObjKind, ObjRelocKind, ObjSections},
util::{
config::{is_auto_jump_table, is_auto_label, is_auto_symbol},
config::{is_auto_jump_table, is_auto_label, is_auto_symbol, parse_u32},
nested::NestedVec,
split::is_linker_generated_label,
},
Expand Down Expand Up @@ -477,6 +477,40 @@ impl ObjSymbols {
Ok(result)
}

/// Locate a symbol by name, with optional reference attributes. Example:
/// `symbol_name!.data:0x1234` will find the symbol named `symbol_name`
/// in the `.data` section at address `0x1234`.
pub fn by_ref<'a>(
&'a self,
sections: &ObjSections,
symbol_ref: &str,
) -> Result<Option<(SymbolIndex, &'a ObjSymbol)>> {
if let Some((name, rest)) = symbol_ref.split_once('!') {
let (section_index, address) = if let Some((section_name, rest)) = rest.split_once(':')
{
let section_index = sections
.by_name(section_name)?
.map(|(idx, _)| idx)
.ok_or_else(|| anyhow!("Section not found: {}", section_name))?;
(Some(section_index), parse_u32(rest)?)
} else {
(None, parse_u32(rest)?)
};
let mut out = None;
for (index, symbol) in self.for_name(name) {
if (section_index.is_none() || symbol.section == section_index)
&& symbol.address == address as u64
{
ensure!(out.is_none(), "Multiple symbols matched {}", symbol_ref);
out = Some((index, symbol));
}
}
Ok(out)
} else {
self.by_name(symbol_ref)
}
}

pub fn by_kind(
&self,
kind: ObjSymbolKind,
Expand Down

0 comments on commit 61cd72c

Please sign in to comment.