diff options
| author | cadmic <cadmic24@gmail.com> | 2026-07-30 22:28:40 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-31 07:28:40 +0200 |
| commit | 32b88f90a86a024dae0af0dc28a2c5e023fd193a (patch) | |
| tree | c6abd43184bb805c5da7dd12c4af00781e761175 | |
| parent | 269d03016cd0e3d7a0b8925e02b97a319c1d0e8d (diff) | |
Fix fix_bss.py tiebreaking algorithm (#2779)
| -rwxr-xr-x | tools/fix_bss.py | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/tools/fix_bss.py b/tools/fix_bss.py index 4c9d22937..d6200a357 100755 --- a/tools/fix_bss.py +++ b/tools/fix_bss.py @@ -32,7 +32,6 @@ from ido_block_numbers import ( import elftools.elf.elffile import mapfile_parser.mapfile - # Set on program start since we replace sys.stdout in worker processes stdout_isatty = sys.stdout.isatty() @@ -337,6 +336,7 @@ class Pragma: @dataclass class BssVariable: block_number: int + is_top_level: bool name: str size: int align: int @@ -395,9 +395,12 @@ def find_bss_variables( if block_number in init_block_numbers: continue # not BSS - name = symbol_table[block_number].name if op.opcode_name == "fsym": - name = f"{last_function_name}::{name}" + name = f"{last_function_name}::{symbol_table[block_number].name}" + is_top_level = False + else: + name = symbol_table[block_number].name + is_top_level = True size = op.args[0] align = 1 << op.lexlev @@ -408,7 +411,9 @@ def find_bss_variables( referenced_in_data = block_number in referenced_in_data_block_numbers bss_variables.append( - BssVariable(block_number, name, size, align, referenced_in_data) + BssVariable( + block_number, is_top_level, name, size, align, referenced_in_data + ) ) elif op.opcode_name == "init": if op.dtype == 10: # Ndt, "non-local label" @@ -439,10 +444,16 @@ def predict_bss_ordering(variables: list[BssVariable]) -> list[BssSymbol]: # For variables referenced in .data or .rodata, keep the original order. referenced_in_data = [var for var in variables if var.referenced_in_data] - # For the others, sort by block number mod 256. For ties, sort by block number. + # For the others, sort by block number mod 256. Ties are broken with the following priority: + # 1. top-level global and static variables, in original (block number) order + # 2. in-function static variables, in reverse order not_referenced_in_data = [var for var in variables if not var.referenced_in_data] not_referenced_in_data.sort( - key=lambda var: (var.block_number % 256, var.block_number) + key=lambda var: ( + var.block_number % 256, + not var.is_top_level, + var.block_number if var.is_top_level else -var.block_number, + ) ) sorted_variables = referenced_in_data + not_referenced_in_data @@ -588,6 +599,7 @@ def solve_bss_ordering( new_bss_variables.append( BssVariable( new_block_number, + var.is_top_level, var.name, var.size, var.align, |
