(
arch: &dyn Arch,
obj_file: &object::File,
sections: &[Section],
section_indices: &[usize],
split_meta: Option<&SplitMeta>,
config: &DiffObjConfig,
)
| 179 | } |
| 180 | |
| 181 | fn map_symbols( |
| 182 | arch: &dyn Arch, |
| 183 | obj_file: &object::File, |
| 184 | sections: &[Section], |
| 185 | section_indices: &[usize], |
| 186 | split_meta: Option<&SplitMeta>, |
| 187 | config: &DiffObjConfig, |
| 188 | ) -> Result<(Vec<Symbol>, Vec<usize>)> { |
| 189 | // symbols() is not guaranteed to be sorted by address. |
| 190 | // We sort it here to fix pairing bugs with diff algorithms that assume the symbols are ordered. |
| 191 | // Sorting everything here once is less expensive than sorting subsets later in expensive loops. |
| 192 | let mut max_index = 0; |
| 193 | let mut obj_symbols = obj_file |
| 194 | .symbols() |
| 195 | .filter(|s| s.kind() != object::SymbolKind::File) |
| 196 | .inspect(|sym| max_index = max_index.max(sym.index().0)) |
| 197 | .collect::<Vec<_>>(); |
| 198 | obj_symbols.sort_by(|a, b| { |
| 199 | // Sort symbols by section index, placing absolute symbols last |
| 200 | a.section_index() |
| 201 | .map_or(usize::MAX, |s| s.0) |
| 202 | .cmp(&b.section_index().map_or(usize::MAX, |s| s.0)) |
| 203 | .then_with(|| { |
| 204 | // Sort section symbols first in a section |
| 205 | if a.kind() == object::SymbolKind::Section { |
| 206 | Ordering::Less |
| 207 | } else if b.kind() == object::SymbolKind::Section { |
| 208 | Ordering::Greater |
| 209 | } else { |
| 210 | Ordering::Equal |
| 211 | } |
| 212 | }) |
| 213 | // Sort by address within section |
| 214 | .then_with(|| a.address().cmp(&b.address())) |
| 215 | // If there are multiple symbols with the same address, smaller symbol first |
| 216 | .then_with(|| a.size().cmp(&b.size())) |
| 217 | }); |
| 218 | let mut symbols = Vec::<Symbol>::with_capacity(obj_symbols.len() + obj_file.sections().count()); |
| 219 | let mut symbol_indices = vec![usize::MAX; max_index + 1]; |
| 220 | for obj_symbol in obj_symbols { |
| 221 | let symbol = map_symbol(arch, obj_file, &obj_symbol, section_indices, split_meta, config)?; |
| 222 | symbol_indices[obj_symbol.index().0] = symbols.len(); |
| 223 | symbols.push(symbol); |
| 224 | } |
| 225 | |
| 226 | // Infer symbol sizes for 0-size symbols |
| 227 | infer_symbol_sizes(arch, &mut symbols, sections)?; |
| 228 | |
| 229 | Ok((symbols, symbol_indices)) |
| 230 | } |
| 231 | |
| 232 | /// Add an extra fake symbol to the start of each data section in order to allow the user to diff |
| 233 | /// all of the data in the section at once by clicking on this fake symbol at the top of the list. |
no test coverage detected