(arch: &dyn Arch, symbols: &mut [Symbol], sections: &[Section])
| 286 | } |
| 287 | |
| 288 | fn infer_symbol_sizes(arch: &dyn Arch, symbols: &mut [Symbol], sections: &[Section]) -> Result<()> { |
| 289 | // Above, we've sorted the symbols by section and then by address. |
| 290 | |
| 291 | // Set symbol sizes based on the next symbol's address |
| 292 | let mut iter_idx = 0; |
| 293 | let mut last_end = (0, 0); |
| 294 | while iter_idx < symbols.len() { |
| 295 | let symbol_idx = iter_idx; |
| 296 | let symbol = &symbols[symbol_idx]; |
| 297 | let Some(section_idx) = symbol.section else { |
| 298 | // Start of absolute symbols |
| 299 | break; |
| 300 | }; |
| 301 | iter_idx += 1; |
| 302 | if symbol.size != 0 { |
| 303 | if symbol.kind != SymbolKind::Section { |
| 304 | last_end = (section_idx, symbol.address + symbol.size); |
| 305 | } |
| 306 | continue; |
| 307 | } |
| 308 | // Skip over symbols that are contained within the previous symbol |
| 309 | if last_end.0 == section_idx && last_end.1 > symbol.address { |
| 310 | continue; |
| 311 | } |
| 312 | let next_symbol = loop { |
| 313 | let Some(next_symbol) = symbols.get(iter_idx) else { |
| 314 | break None; |
| 315 | }; |
| 316 | if next_symbol.section != Some(section_idx) { |
| 317 | break None; |
| 318 | } |
| 319 | if match symbol.kind { |
| 320 | SymbolKind::Function | SymbolKind::Object => { |
| 321 | // For function/object symbols, find the next function/object |
| 322 | matches!(next_symbol.kind, SymbolKind::Function | SymbolKind::Object) |
| 323 | } |
| 324 | SymbolKind::Unknown | SymbolKind::Section => { |
| 325 | // For labels (or anything else), stop at any symbol |
| 326 | true |
| 327 | } |
| 328 | } && !is_local_label(next_symbol) |
| 329 | { |
| 330 | break Some(next_symbol); |
| 331 | } |
| 332 | iter_idx += 1; |
| 333 | }; |
| 334 | let section = §ions[section_idx]; |
| 335 | let next_address = |
| 336 | next_symbol.map(|s| s.address).unwrap_or_else(|| section.address + section.size); |
| 337 | let new_size = if symbol.kind == SymbolKind::Section && section.kind == SectionKind::Data { |
| 338 | // Data sections already have always-visible section symbols created by objdiff to allow |
| 339 | // diffing them, so no need to unhide these. |
| 340 | 0 |
| 341 | } else if section.kind == SectionKind::Code { |
| 342 | arch.infer_function_size(symbol, section, next_address)? |
| 343 | } else { |
| 344 | next_address.saturating_sub(symbol.address) |
| 345 | }; |
no test coverage detected