()
| 406 | |
| 407 | |
| 408 | def main() -> int: |
| 409 | print("Loading sections...") |
| 410 | sections = parse_sections() |
| 411 | loadable = [s for s in sections if s.is_loadable] |
| 412 | total_loaded = sum(s.size for s in loadable) |
| 413 | print( |
| 414 | f" Found {len(loadable)} loadable sections, total loadable bytes = {total_loaded:,}" |
| 415 | ) |
| 416 | for s in sorted(loadable, key=lambda x: -x.size): |
| 417 | print( |
| 418 | f" {s.name:<22} size={s.size:>8,} addr=0x{s.addr:08x} flags={s.flags}" |
| 419 | ) |
| 420 | |
| 421 | print("\nLoading nm symbols...") |
| 422 | raw = parse_nm_symbols() |
| 423 | print(f" {len(raw):,} symbols with size from nm") |
| 424 | |
| 425 | print("Demangling...") |
| 426 | mangled_names = list({m for _, _, _, m in raw}) |
| 427 | demangled_map = batch_demangle(mangled_names) |
| 428 | |
| 429 | print("Filtering to loadable-section symbols...") |
| 430 | in_bin: list[Symbol] = [] |
| 431 | skipped = 0 |
| 432 | for addr, size, t, mangled in raw: |
| 433 | sec = loaded_section_for(addr, sections) |
| 434 | if sec is None: |
| 435 | skipped += 1 |
| 436 | continue |
| 437 | in_bin.append( |
| 438 | Symbol( |
| 439 | addr=addr, |
| 440 | size=size, |
| 441 | type=t, |
| 442 | mangled=mangled, |
| 443 | demangled=demangled_map.get(mangled, mangled), |
| 444 | section=sec.name, |
| 445 | ) |
| 446 | ) |
| 447 | print( |
| 448 | f" {len(in_bin):,} symbols in bin, {skipped:,} skipped (debug-only or unaddressed)" |
| 449 | ) |
| 450 | |
| 451 | bin_total = sum(s.size for s in in_bin) |
| 452 | print(f" Sum of nm symbol sizes in bin sections: {bin_total:,} bytes") |
| 453 | |
| 454 | # ===== By section ===== |
| 455 | print("\n=== Top symbols by SECTION (showing where bytes go) ===") |
| 456 | by_sec: dict[str, int] = defaultdict(int) |
| 457 | for s in in_bin: |
| 458 | by_sec[s.section or "?"] += s.size |
| 459 | for sec, size in sorted(by_sec.items(), key=lambda kv: -kv[1]): |
| 460 | print(f" {sec:<22} {size:>8,}") |
| 461 | |
| 462 | # ===== By category ===== |
| 463 | by_cat: dict[str, int] = defaultdict(int) |
| 464 | by_cat_count: dict[str, int] = defaultdict(int) |
| 465 | by_cat_section: dict[tuple[str, str], int] = defaultdict(int) |
no test coverage detected