Skip to content

Commit

Permalink
MapFile.fixupNonMatchingSymbols
Browse files Browse the repository at this point in the history
  • Loading branch information
AngheloAlf committed Aug 26, 2024
1 parent 301a4cb commit 6308dfb
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 4 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Add new parameters to `bss_check.printSymbolComparison`.
- `printGoods`: Allows toggling printing the GOOD symbols.
- `printingStyle`: The style to use to print the symbols, either `"csv"` or `"listing"`.
- `printingStyle`: The style to use to print the symbols, either `"csv"` or
`"listing"`.
- TODO: port to Rust.
- New `MapFile.fixupNonMatchingSymbols` method.
- Allows to fixup size calculation of symbols messed up by symbols with the
same name suffixed with `.NON_MATCHING`.

### Changed

Expand Down
8 changes: 6 additions & 2 deletions src/mapfile_parser/frontends/jsonify.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@
from .. import mapfile


def doJsonify(mapPath: Path, outputPath: Path|None, humanReadable: bool=True) -> int:
def doJsonify(mapPath: Path, outputPath: Path|None, humanReadable: bool=True, applyFixes: bool=False) -> int:
if not mapPath.exists():
print(f"Could not find mapfile at '{mapPath}'")
return 1

mapFile = mapfile.MapFile()
mapFile.readMapFile(mapPath)
if applyFixes:
mapFile = mapFile.fixupNonMatchingSymbols()

jsonStr = json.dumps(mapFile.toJson(humanReadable=humanReadable), indent=4)

Expand All @@ -35,14 +37,16 @@ def processArguments(args: argparse.Namespace):
mapPath: Path = args.mapfile
outputPath: Path|None = Path(args.output) if args.output is not None else None
machine: bool = args.machine
applyFixes: bool = args.applyFixes

exit(doJsonify(mapPath, outputPath, humanReadable=not machine))
exit(doJsonify(mapPath, outputPath, humanReadable=not machine, applyFixes=applyFixes))

def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser]):
parser = subparser.add_parser("jsonify", help="Converts a mapfile into a json format.")

parser.add_argument("mapfile", help="Path to a map file", type=Path)
parser.add_argument("-o", "--output", help="Output path of for the generated json. If omitted then stdout is used instead.")
parser.add_argument("-m", "--machine", help="Emit numbers as numbers instead of outputting them as pretty strings.", action="store_true")
parser.add_argument("-f", "--apply-fixes", help="Apply certain fixups, like fixing size calculation of because of the existence of fake `.NON_MATCHING` symbols.", action="store_true")

parser.set_defaults(func=processArguments)
2 changes: 1 addition & 1 deletion src/mapfile_parser/frontends/progress.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def getProgress(mapPath: Path, asmPath: Path, nonmatchingsPath: Path, pathIndex:
mapFile.debugging = debugging
mapFile.readMapFile(mapPath)

return mapFile.filterBySectionType(".text").getProgress(asmPath, nonmatchingsPath, pathIndex=pathIndex)
return mapFile.filterBySectionType(".text").fixupNonMatchingSymbols().getProgress(asmPath, nonmatchingsPath, pathIndex=pathIndex)

def doProgress(mapPath: Path, asmPath: Path, nonmatchingsPath: Path, pathIndex: int=2, debugging: bool=False) -> int:
if not mapPath.exists():
Expand Down
40 changes: 40 additions & 0 deletions src/mapfile_parser/mapfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ def toJson(self, humanReadable: bool=True) -> dict[str, Any]:
return result


def clone(self) -> Symbol:
return Symbol(self.name, self.vram, self.size, self.vrom, self.align)


def __eq__(self, other: object) -> bool:
if not isinstance(other, Symbol):
return False
Expand Down Expand Up @@ -302,6 +306,13 @@ def appendSymbol(self, sym: Symbol) -> None:
self._symbols.append(sym)


def clone(self) -> File:
f = File(self.filepath, self.vram, self.size, self.sectionType, self.vrom, self.align)
for sym in self._symbols:
f._symbols.append(sym.clone())
return f


def __iter__(self) -> Generator[Symbol, None, None]:
for sym in self._symbols:
yield sym
Expand Down Expand Up @@ -476,6 +487,13 @@ def appendFile(self, file: File) -> None:
self._filesList.append(file)


def clone(self) -> Segment:
s = Segment(self.name, self.vram, self.size, self.vrom, self.align)
for f in self._filesList:
s._filesList.append(f.clone())
return s


def __iter__(self) -> Generator[File, None, None]:
for file in self._filesList:
yield file
Expand Down Expand Up @@ -672,6 +690,20 @@ def mixFolders(self) -> MapFile:

return newMapFile

def fixupNonMatchingSymbols(self) -> MapFile:
newMapFile = self.clone()

for segment in newMapFile._segmentsList:
for file in segment._filesList:
for sym in file._symbols:
if sym.name.endswith(".NON_MATCHING") and sym.size != 0:
realSym = file.findSymbolByName(sym.name.replace(".NON_MATCHING", ""))
if realSym is not None and realSym.size == 0:
realSym.size = sym.size
sym.size = 0

return newMapFile

def getProgress(self, asmPath: Path, nonmatchings: Path, aliases: dict[str, str]=dict(), pathIndex: int=2) -> tuple[ProgressStats, dict[str, ProgressStats]]:
totalStats = ProgressStats()
progressPerFolder: dict[str, ProgressStats] = dict()
Expand Down Expand Up @@ -810,6 +842,14 @@ def appendSegment(self, segment: Segment) -> None:
self._segmentsList.append(segment)


def clone(self) -> MapFile:
m = MapFile()
m.debugging = self.debugging
for s in self._segmentsList:
m._segmentsList.append(s.clone())
return m


def __iter__(self) -> Generator[Segment, None, None]:
for file in self._segmentsList:
yield file
Expand Down
43 changes: 43 additions & 0 deletions src/rs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ impl File {
self.symbols.iter().find(|&sym| sym.name == sym_name)
}

pub fn find_symbol_and_index_by_name(
&self,
sym_name: &str,
) -> Option<(&symbol::Symbol, usize)> {
for (index, sym) in self.symbols.iter().enumerate() {
if sym.name == sym_name {
return Some((sym, index));
}
}
None
}

pub fn find_symbol_by_name_mut(&mut self, sym_name: &str) -> Option<&mut symbol::Symbol> {
self.symbols.iter_mut().find(|sym| sym.name == sym_name)
}

pub fn find_symbol_by_vram_or_vrom(&self, address: u64) -> Option<(&symbol::Symbol, i64)> {
let mut prev_sym: Option<&symbol::Symbol> = None;

Expand Down Expand Up @@ -126,6 +142,29 @@ impl File {
None
}

pub fn fixup_non_matching_symbols(&mut self) {
let mut symbols_to_fix = Vec::new();

for (index, sym) in self.symbols.iter().enumerate() {
if sym.name.ends_with(".NON_MATCHING") && sym.size.is_some() && sym.size == Some(0) {
let real_name = sym.name.replace(".NON_MATCHING", "");

if let Some((_real_sym, real_index)) =
self.find_symbol_and_index_by_name(&real_name)
{
symbols_to_fix.push((real_index, sym.size));
symbols_to_fix.push((index, Some(0)));
}
}
}

for (index, new_size) in symbols_to_fix {
if let Some(sym) = self.symbols.get_mut(index) {
sym.size = new_size;
}
}
}

pub fn to_csv_header(print_vram: bool) -> String {
let mut ret = String::new();

Expand Down Expand Up @@ -397,6 +436,10 @@ pub(crate) mod python_bindings {
}
}

fn fixupNonMatchingSymbols(&mut self) {
self.fixup_non_matching_symbols()
}

#[staticmethod]
#[pyo3(signature=(print_vram=true))]
fn toCsvHeader(print_vram: bool) -> String {
Expand Down
15 changes: 15 additions & 0 deletions src/rs/mapfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,17 @@ impl MapFile {
new_map_file
}

pub fn fixup_non_matching_symbols(&self) -> Self {
let mut new_map_file = self.clone();

new_map_file
.segments_list
.iter_mut()
.for_each(|x| x.fixup_non_matching_symbols());

new_map_file
}

pub fn get_progress(
&self,
asm_path: &Path,
Expand Down Expand Up @@ -867,6 +878,10 @@ pub(crate) mod python_bindings {
self.mix_folders()
}

fn fixupNonMatchingSymbols(&self) -> Self {
self.fixup_non_matching_symbols()
}

#[pyo3(signature = (asm_path, nonmatchings, aliases=HashMap::new(), path_index=2))]
fn getProgress(
&self,
Expand Down
10 changes: 10 additions & 0 deletions src/rs/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ impl Segment {
new_segment
}

pub fn fixup_non_matching_symbols(&mut self) {
self.files_list
.iter_mut()
.for_each(|x| x.fixup_non_matching_symbols())
}

pub fn to_csv(&self, print_vram: bool, skip_without_symbols: bool) -> String {
let mut ret = String::new();

Expand Down Expand Up @@ -385,6 +391,10 @@ pub(crate) mod python_bindings {
self.mix_folders()
}

fn fixupNonMatchingSymbols(&mut self) {
self.fixup_non_matching_symbols()
}

#[pyo3(signature=(print_vram=true, skip_without_symbols=true))]
fn toCsv(&self, print_vram: bool, skip_without_symbols: bool) -> String {
self.to_csv(print_vram, skip_without_symbols)
Expand Down

0 comments on commit 6308dfb

Please sign in to comment.