mirror of https://github.com/encounter/objdiff.git
Deprioritize generated GCC symbols in find_section_symbol
Resolves #115
This commit is contained in:
parent
9596051cb4
commit
ab2e84a2c6
|
@ -152,16 +152,15 @@ fn symbols_by_section(
|
||||||
arch: &dyn ObjArch,
|
arch: &dyn ObjArch,
|
||||||
obj_file: &File<'_>,
|
obj_file: &File<'_>,
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
|
section_symbols: &[Symbol<'_, '_>],
|
||||||
split_meta: Option<&SplitMeta>,
|
split_meta: Option<&SplitMeta>,
|
||||||
name_counts: &mut HashMap<String, u32>,
|
name_counts: &mut HashMap<String, u32>,
|
||||||
) -> Result<Vec<ObjSymbol>> {
|
) -> Result<Vec<ObjSymbol>> {
|
||||||
let mut result = Vec::<ObjSymbol>::new();
|
let mut result = Vec::<ObjSymbol>::new();
|
||||||
for symbol in obj_file.symbols() {
|
for symbol in section_symbols {
|
||||||
if symbol.kind() == SymbolKind::Section {
|
if symbol.kind() == SymbolKind::Section {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(index) = symbol.section().index() {
|
|
||||||
if index.0 == section.orig_index {
|
|
||||||
if symbol.is_local() && section.kind == ObjSectionKind::Code {
|
if symbol.is_local() && section.kind == ObjSectionKind::Code {
|
||||||
// TODO strip local syms in diff?
|
// TODO strip local syms in diff?
|
||||||
let name = symbol.name().context("Failed to process symbol name")?;
|
let name = symbol.name().context("Failed to process symbol name")?;
|
||||||
|
@ -169,9 +168,7 @@ fn symbols_by_section(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.push(to_obj_symbol(arch, obj_file, &symbol, 0, split_meta)?);
|
result.push(to_obj_symbol(arch, obj_file, symbol, 0, split_meta)?);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result.sort_by(|a, b| a.address.cmp(&b.address).then(a.size.cmp(&b.size)));
|
result.sort_by(|a, b| a.address.cmp(&b.address).then(a.size.cmp(&b.size)));
|
||||||
let mut iter = result.iter_mut().peekable();
|
let mut iter = result.iter_mut().peekable();
|
||||||
|
@ -221,47 +218,71 @@ fn common_symbols(
|
||||||
.collect::<Result<Vec<ObjSymbol>>>()
|
.collect::<Result<Vec<ObjSymbol>>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LOW_PRIORITY_SYMBOLS: &[&str] =
|
||||||
|
&["__gnu_compiled_c", "__gnu_compiled_cplusplus", "gcc2_compiled."];
|
||||||
|
|
||||||
|
fn best_symbol<'r, 'data, 'file>(
|
||||||
|
symbols: &'r [Symbol<'data, 'file>],
|
||||||
|
address: u64,
|
||||||
|
) -> Option<&'r Symbol<'data, 'file>> {
|
||||||
|
let closest_symbol_index = match symbols.binary_search_by_key(&address, |s| s.address()) {
|
||||||
|
Ok(index) => Some(index),
|
||||||
|
Err(index) => index.checked_sub(1),
|
||||||
|
}?;
|
||||||
|
let mut best_symbol: Option<&'r Symbol<'data, 'file>> = None;
|
||||||
|
for symbol in symbols.iter().skip(closest_symbol_index) {
|
||||||
|
if symbol.address() > address {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if symbol.kind() == SymbolKind::Section
|
||||||
|
|| (symbol.size() > 0 && (symbol.address() + symbol.size()) <= address)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// TODO priority ranking with visibility, etc
|
||||||
|
if let Some(best) = best_symbol {
|
||||||
|
if LOW_PRIORITY_SYMBOLS.contains(&best.name().unwrap_or_default())
|
||||||
|
&& !LOW_PRIORITY_SYMBOLS.contains(&symbol.name().unwrap_or_default())
|
||||||
|
{
|
||||||
|
best_symbol = Some(symbol);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
best_symbol = Some(symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
best_symbol
|
||||||
|
}
|
||||||
|
|
||||||
fn find_section_symbol(
|
fn find_section_symbol(
|
||||||
arch: &dyn ObjArch,
|
arch: &dyn ObjArch,
|
||||||
obj_file: &File<'_>,
|
obj_file: &File<'_>,
|
||||||
|
section_symbols: &[Symbol<'_, '_>],
|
||||||
target: &Symbol<'_, '_>,
|
target: &Symbol<'_, '_>,
|
||||||
address: u64,
|
address: u64,
|
||||||
split_meta: Option<&SplitMeta>,
|
split_meta: Option<&SplitMeta>,
|
||||||
) -> Result<ObjSymbol> {
|
) -> Result<ObjSymbol> {
|
||||||
|
if let Some(symbol) = best_symbol(section_symbols, address) {
|
||||||
|
return to_obj_symbol(
|
||||||
|
arch,
|
||||||
|
obj_file,
|
||||||
|
symbol,
|
||||||
|
address as i64 - symbol.address() as i64,
|
||||||
|
split_meta,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Fallback to section symbol
|
||||||
let section_index =
|
let section_index =
|
||||||
target.section_index().ok_or_else(|| anyhow::Error::msg("Unknown section index"))?;
|
target.section_index().ok_or_else(|| anyhow::Error::msg("Unknown section index"))?;
|
||||||
let section = obj_file.section_by_index(section_index)?;
|
let section = obj_file.section_by_index(section_index)?;
|
||||||
let mut closest_symbol: Option<Symbol<'_, '_>> = None;
|
|
||||||
for symbol in obj_file.symbols() {
|
|
||||||
if !matches!(symbol.section_index(), Some(idx) if idx == section_index) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if symbol.kind() == SymbolKind::Section || symbol.address() != address {
|
|
||||||
if symbol.address() < address
|
|
||||||
&& symbol.size() != 0
|
|
||||||
&& (closest_symbol.is_none()
|
|
||||||
|| matches!(&closest_symbol, Some(s) if s.address() <= symbol.address()))
|
|
||||||
{
|
|
||||||
closest_symbol = Some(symbol);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return to_obj_symbol(arch, obj_file, &symbol, 0, split_meta);
|
|
||||||
}
|
|
||||||
let (name, offset) = closest_symbol
|
|
||||||
.and_then(|s| s.name().map(|n| (n, s.address())).ok())
|
|
||||||
.or_else(|| section.name().map(|n| (n, section.address())).ok())
|
|
||||||
.unwrap_or(("<unknown>", 0));
|
|
||||||
let offset_addr = address - offset;
|
|
||||||
Ok(ObjSymbol {
|
Ok(ObjSymbol {
|
||||||
name: name.to_string(),
|
name: section.name()?.to_string(),
|
||||||
demangled_name: None,
|
demangled_name: None,
|
||||||
address: offset,
|
address: section.address(),
|
||||||
section_address: address - section.address(),
|
section_address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
size_known: false,
|
size_known: false,
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
addend: offset_addr as i64,
|
addend: address as i64 - section.address() as i64,
|
||||||
virtual_address: None,
|
virtual_address: None,
|
||||||
original_index: None,
|
original_index: None,
|
||||||
bytes: Vec::new(),
|
bytes: Vec::new(),
|
||||||
|
@ -272,6 +293,7 @@ fn relocations_by_section(
|
||||||
arch: &dyn ObjArch,
|
arch: &dyn ObjArch,
|
||||||
obj_file: &File<'_>,
|
obj_file: &File<'_>,
|
||||||
section: &ObjSection,
|
section: &ObjSection,
|
||||||
|
section_symbols: &[Symbol<'_, '_>],
|
||||||
split_meta: Option<&SplitMeta>,
|
split_meta: Option<&SplitMeta>,
|
||||||
) -> Result<Vec<ObjReloc>> {
|
) -> Result<Vec<ObjReloc>> {
|
||||||
let obj_section = obj_file.section_by_index(SectionIndex(section.orig_index))?;
|
let obj_section = obj_file.section_by_index(SectionIndex(section.orig_index))?;
|
||||||
|
@ -315,7 +337,14 @@ fn relocations_by_section(
|
||||||
}
|
}
|
||||||
SymbolKind::Section => {
|
SymbolKind::Section => {
|
||||||
ensure!(addend >= 0, "Negative addend in reloc: {addend}");
|
ensure!(addend >= 0, "Negative addend in reloc: {addend}");
|
||||||
find_section_symbol(arch, obj_file, &symbol, addend as u64, split_meta)
|
find_section_symbol(
|
||||||
|
arch,
|
||||||
|
obj_file,
|
||||||
|
section_symbols,
|
||||||
|
&symbol,
|
||||||
|
addend as u64,
|
||||||
|
split_meta,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
kind => Err(anyhow!("Unhandled relocation symbol type {kind:?}")),
|
kind => Err(anyhow!("Unhandled relocation symbol type {kind:?}")),
|
||||||
}?;
|
}?;
|
||||||
|
@ -650,15 +679,26 @@ pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result<ObjInfo> {
|
||||||
let mut sections = filter_sections(&obj_file, split_meta.as_ref())?;
|
let mut sections = filter_sections(&obj_file, split_meta.as_ref())?;
|
||||||
let mut name_counts: HashMap<String, u32> = HashMap::new();
|
let mut name_counts: HashMap<String, u32> = HashMap::new();
|
||||||
for section in &mut sections {
|
for section in &mut sections {
|
||||||
|
let mut symbols = obj_file
|
||||||
|
.symbols()
|
||||||
|
.filter(|s| s.section_index() == Some(SectionIndex(section.orig_index)))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
symbols.sort_by_key(|s| s.address());
|
||||||
section.symbols = symbols_by_section(
|
section.symbols = symbols_by_section(
|
||||||
arch.as_ref(),
|
arch.as_ref(),
|
||||||
&obj_file,
|
&obj_file,
|
||||||
section,
|
section,
|
||||||
|
&symbols,
|
||||||
split_meta.as_ref(),
|
split_meta.as_ref(),
|
||||||
&mut name_counts,
|
&mut name_counts,
|
||||||
)?;
|
)?;
|
||||||
section.relocations =
|
section.relocations = relocations_by_section(
|
||||||
relocations_by_section(arch.as_ref(), &obj_file, section, split_meta.as_ref())?;
|
arch.as_ref(),
|
||||||
|
&obj_file,
|
||||||
|
section,
|
||||||
|
&symbols,
|
||||||
|
split_meta.as_ref(),
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
if config.combine_data_sections {
|
if config.combine_data_sections {
|
||||||
combine_data_sections(&mut sections)?;
|
combine_data_sections(&mut sections)?;
|
||||||
|
|
Loading…
Reference in New Issue