mirror of
https://github.com/zeldaret/oot
synced 2026-08-04 09:09:22 -04:00
Fix fix_bss.py tiebreaking algorithm (#2779)
This commit is contained in:
+18
-6
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user