|
1 |
| -use std::{collections::{HashMap, HashSet}, fs, io::Cursor, mem::size_of, path::Path}; |
| 1 | +use std::{ |
| 2 | + collections::{HashMap, HashSet}, |
| 3 | + fs, |
| 4 | + io::Cursor, |
| 5 | + mem::size_of, |
| 6 | + path::Path, |
| 7 | +}; |
2 | 8 |
|
3 | 9 | use anyhow::{anyhow, bail, ensure, Context, Result};
|
4 | 10 | use filetime::FileTime;
|
@@ -136,6 +142,7 @@ fn symbols_by_section(
|
136 | 142 | obj_file: &File<'_>,
|
137 | 143 | section: &ObjSection,
|
138 | 144 | split_meta: Option<&SplitMeta>,
|
| 145 | + name_counts: &mut HashMap<String, u32>, |
139 | 146 | ) -> Result<Vec<ObjSymbol>> {
|
140 | 147 | let mut result = Vec::<ObjSymbol>::new();
|
141 | 148 | for symbol in obj_file.symbols() {
|
@@ -168,8 +175,14 @@ fn symbols_by_section(
|
168 | 175 | }
|
169 | 176 | if result.is_empty() {
|
170 | 177 | // Dummy symbol for empty sections
|
| 178 | + *name_counts.entry(section.name.clone()).or_insert(0) += 1; |
| 179 | + let current_count: u32 = *name_counts.get(§ion.name).unwrap(); |
171 | 180 | result.push(ObjSymbol {
|
172 |
| - name: format!("[{}]", section.name), |
| 181 | + name: if current_count > 1 { |
| 182 | + format!("[{} ({})]", section.name, current_count) |
| 183 | + } else { |
| 184 | + format!("[{}]", section.name) |
| 185 | + }, |
173 | 186 | demangled_name: None,
|
174 | 187 | address: 0,
|
175 | 188 | section_address: 0,
|
@@ -621,33 +634,18 @@ pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result<ObjInfo> {
|
621 | 634 | let arch = new_arch(&obj_file)?;
|
622 | 635 | let split_meta = split_meta(&obj_file)?;
|
623 | 636 | let mut sections = filter_sections(&obj_file, split_meta.as_ref())?;
|
| 637 | + let mut name_counts: HashMap<String, u32> = HashMap::new(); |
624 | 638 | for section in &mut sections {
|
625 |
| - section.symbols = |
626 |
| - symbols_by_section(arch.as_ref(), &obj_file, section, split_meta.as_ref())?; |
| 639 | + section.symbols = symbols_by_section( |
| 640 | + arch.as_ref(), |
| 641 | + &obj_file, |
| 642 | + section, |
| 643 | + split_meta.as_ref(), |
| 644 | + &mut name_counts, |
| 645 | + )?; |
627 | 646 | section.relocations =
|
628 | 647 | relocations_by_section(arch.as_ref(), &obj_file, section, split_meta.as_ref())?;
|
629 | 648 | }
|
630 |
| - // The dummy symbols all have the same name, which means that only the first one can be |
631 |
| - // compared |
632 |
| - let all_names = sections |
633 |
| - .iter() |
634 |
| - .flat_map(|section| section.symbols.iter().map(|symbol| symbol.name.clone())); |
635 |
| - let mut name_counts: HashMap<String, usize> = HashMap::new(); |
636 |
| - for name in all_names { |
637 |
| - name_counts.entry(name).and_modify(|i| *i += 1).or_insert(1); |
638 |
| - } |
639 |
| - // Reversing the iterator here means the symbol sections will be given in the expected order |
640 |
| - // since they're assigned from the count down to prevent |
641 |
| - // having to use another hashmap which counts up |
642 |
| - // TODO what about reverse_fn_order? |
643 |
| - for section in sections.iter_mut().rev() { |
644 |
| - for symbol in section.symbols.iter_mut().rev() { |
645 |
| - if name_counts[&symbol.name] > 1 { |
646 |
| - name_counts.entry(symbol.name.clone()).and_modify(|i| *i -= 1); |
647 |
| - symbol.name = format!("{} ({})", &symbol.name, name_counts[&symbol.name]); |
648 |
| - } |
649 |
| - } |
650 |
| - } |
651 | 649 | if config.combine_data_sections {
|
652 | 650 | combine_data_sections(&mut sections)?;
|
653 | 651 | }
|
|
0 commit comments