Support duplicate filenames in ELF loader
This commit is contained in:
parent
9f4cc2f542
commit
d76c554d31
|
@ -1,4 +1,8 @@
|
||||||
use std::{collections::BTreeMap, fs::File, path::Path};
|
use std::{
|
||||||
|
collections::{hash_map, BTreeMap, HashMap},
|
||||||
|
fs::File,
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::{Context, Error, Result};
|
use anyhow::{Context, Error, Result};
|
||||||
use cwdemangle::demangle;
|
use cwdemangle::demangle;
|
||||||
|
@ -74,6 +78,7 @@ pub fn process_elf<P: AsRef<Path>>(path: P) -> Result<ObjInfo> {
|
||||||
relocations: vec![],
|
relocations: vec![],
|
||||||
original_address: 0, // TODO load from abs symbol
|
original_address: 0, // TODO load from abs symbol
|
||||||
file_offset: section.file_range().map(|(v, _)| v).unwrap_or_default(),
|
file_offset: section.file_range().map(|(v, _)| v).unwrap_or_default(),
|
||||||
|
section_known: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +86,7 @@ pub fn process_elf<P: AsRef<Path>>(path: P) -> Result<ObjInfo> {
|
||||||
let mut symbol_indexes: Vec<Option<usize>> = vec![];
|
let mut symbol_indexes: Vec<Option<usize>> = vec![];
|
||||||
let mut current_file: Option<String> = None;
|
let mut current_file: Option<String> = None;
|
||||||
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
|
||||||
for symbol in obj_file.symbols() {
|
for symbol in obj_file.symbols() {
|
||||||
// Locate linker-generated symbols
|
// Locate linker-generated symbols
|
||||||
let symbol_name = symbol.name()?;
|
let symbol_name = symbol.name()?;
|
||||||
|
@ -106,15 +112,25 @@ pub fn process_elf<P: AsRef<Path>>(path: P) -> Result<ObjInfo> {
|
||||||
match symbol.kind() {
|
match symbol.kind() {
|
||||||
// Detect file boundaries
|
// Detect file boundaries
|
||||||
SymbolKind::File => {
|
SymbolKind::File => {
|
||||||
let file_name = symbol_name.to_string();
|
let mut file_name = symbol_name.to_string();
|
||||||
if kind == ObjKind::Relocatable {
|
if kind == ObjKind::Relocatable {
|
||||||
obj_name = file_name.clone();
|
obj_name = file_name.clone();
|
||||||
}
|
}
|
||||||
match section_starts.entry(file_name.clone()) {
|
match section_starts.entry(file_name.clone()) {
|
||||||
indexmap::map::Entry::Occupied(_) => {
|
indexmap::map::Entry::Occupied(_) => {
|
||||||
return Err(Error::msg(format!("Duplicate file name: {file_name}")));
|
let index = match name_to_index.entry(file_name.clone()) {
|
||||||
|
hash_map::Entry::Occupied(mut e) => e.into_mut(),
|
||||||
|
hash_map::Entry::Vacant(e) => e.insert(0),
|
||||||
|
};
|
||||||
|
*index += 1;
|
||||||
|
let new_name = format!("{}_{}", file_name, index);
|
||||||
|
log::info!("Renaming {} to {}", file_name, new_name);
|
||||||
|
section_starts.insert(new_name.clone(), Default::default());
|
||||||
|
file_name = new_name;
|
||||||
|
}
|
||||||
|
indexmap::map::Entry::Vacant(e) => {
|
||||||
|
e.insert(Default::default());
|
||||||
}
|
}
|
||||||
indexmap::map::Entry::Vacant(e) => e.insert(Default::default()),
|
|
||||||
};
|
};
|
||||||
current_file = Some(file_name);
|
current_file = Some(file_name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue