mapfile-parser 2.9.4__tar.gz → 2.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/CHANGELOG.md +46 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/Cargo.lock +1 -1
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/Cargo.toml +1 -1
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/PKG-INFO +3 -7
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/README.md +2 -2
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/pyproject.toml +1 -1
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/__init__.py +1 -1
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/bss_check.py +40 -8
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/first_diff.py +38 -7
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/jsonify.py +26 -4
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/objdiff_report.py +39 -4
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/pj64_syms.py +25 -4
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/progress.py +44 -11
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/sym_info.py +28 -4
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/symbol_sizes_csv.py +28 -4
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/upload_frogress.py +31 -3
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/mapfile.py +102 -21
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/mapfile_parser.pyi +30 -3
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/mapfile.rs +112 -9
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/parser.rs +120 -20
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/report.rs +25 -50
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/section.rs +1 -1
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/segment.rs +4 -4
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/symbol.rs +36 -4
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/symbol_decomp_state.rs +7 -1
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/.gitattributes +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/.gitignore +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/LICENSE +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/__main__.py +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/__init__.py +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/internals/__init__.py +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/internals/objdiff_report.py +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/mapfile_rs.py +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/progress_stats.py +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/progress_stats_rs.py +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/utils.py +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/found_symbol_info.rs +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/lib.rs +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/maps_comparison_info.rs +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/progress_stats.rs +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/symbol_comparison_info.rs +0 -0
- {mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/rs/utils.rs +0 -0
@@ -7,6 +7,50 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [2.11.0] - 2025-09-08
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- Progress reports using the objdiff's report format can now emit progress for
|
15
|
+
data symbols!
|
16
|
+
- Data progress reporting requires `.NON_MATCHING` markers for every data
|
17
|
+
symbol that is not considered matched yet (i.e. from an automatic disassembly).
|
18
|
+
- It is turned off by default in `objdiff_report`. To turn it on set
|
19
|
+
`report_data: True` on your `decomp.yaml` file.
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
- Mapfile parsing will now try to infer static symbols by analyzing mismatches
|
24
|
+
on section address and size vs the addresses and sizes of symbols within that
|
25
|
+
section.
|
26
|
+
- For every inferred static sym a corresponding symbol will be inserted into
|
27
|
+
the section. Its name will be prefixed with `$_static_symbol_`.
|
28
|
+
- It is possible to check if a symbol is an inferred static in the API by
|
29
|
+
checking `Symbol::inferred_static`.
|
30
|
+
- The `--emit-categories` flag of `objdiff_report` not sets
|
31
|
+
`check_asm_paths: False` and `report_data: True` by default.
|
32
|
+
|
33
|
+
### Fixed
|
34
|
+
|
35
|
+
- Fix the vram address plf-resolved mapfiles when the sections of those plfs
|
36
|
+
were not relative to zero.
|
37
|
+
|
38
|
+
## [2.10.0] - 2025-09-01
|
39
|
+
|
40
|
+
### Added
|
41
|
+
|
42
|
+
- Support for partially linked objects (a.k.a. `plf`).
|
43
|
+
- This is done by calling a function with a user provided callback that
|
44
|
+
converts a given object path into the corresponding mapfile for that `plf`.
|
45
|
+
- Rust: `MapFile::resolve_partially_linked_files()`.
|
46
|
+
- Python: `MapFile::resolvePartiallyLinkedFiles()`.
|
47
|
+
- All the CLI utilities include basic support for `plf`s.
|
48
|
+
- Pass the flag `-x .extension` or `--plf-ext .extension` to specify the
|
49
|
+
extension of the partially linked objects files that should be replaced with
|
50
|
+
a `.map` extension.
|
51
|
+
- The frontends API allow to further customize this behavior by passing a
|
52
|
+
callback like the one used by `MapFile::resolvePartiallyLinkedFiles`.
|
53
|
+
|
10
54
|
## [2.9.4] - 2025-06-02
|
11
55
|
|
12
56
|
### Changed
|
@@ -620,6 +664,8 @@ Full changes: <https://github.com/Decompollaborate/mapfile_parser/compare/702a73
|
|
620
664
|
- Initial release
|
621
665
|
|
622
666
|
[unreleased]: https://github.com/Decompollaborate/mapfile_parser/compare/master...develop
|
667
|
+
[2.11.0]: https://github.com/Decompollaborate/mapfile_parser/compare/2.10.0...2.11.0
|
668
|
+
[2.10.0]: https://github.com/Decompollaborate/mapfile_parser/compare/2.9.4...2.10.0
|
623
669
|
[2.9.4]: https://github.com/Decompollaborate/mapfile_parser/compare/2.9.3...2.9.4
|
624
670
|
[2.9.3]: https://github.com/Decompollaborate/mapfile_parser/compare/2.9.2...2.9.3
|
625
671
|
[2.9.2]: https://github.com/Decompollaborate/mapfile_parser/compare/2.9.1...2.9.2
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mapfile_parser
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.11.0
|
4
4
|
Classifier: Programming Language :: Rust
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
@@ -8,10 +8,6 @@ Requires-Dist: requests
|
|
8
8
|
Requires-Dist: decomp-settings==0.0.9
|
9
9
|
License-File: LICENSE
|
10
10
|
Summary: Map file parser library focusing decompilation projects
|
11
|
-
Keywords: mapfile,parser,decomp,decompilation
|
12
|
-
Author: Anghelo Carvajal <angheloalf95@gmail.com>
|
13
|
-
Author-email: Anghelo Carvajal <angheloalf95@gmail.com>
|
14
|
-
License: MIT
|
15
11
|
Requires-Python: >=3.9
|
16
12
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
17
13
|
Project-URL: Homepage, https://github.com/Decompollaborate/mapfile_parser
|
@@ -55,7 +51,7 @@ If you use a `requirements.txt` file in your repository, then you can add
|
|
55
51
|
this library with the following line:
|
56
52
|
|
57
53
|
```txt
|
58
|
-
mapfile_parser>=2.
|
54
|
+
mapfile_parser>=2.11.0,<3.0.0
|
59
55
|
```
|
60
56
|
|
61
57
|
#### Development version
|
@@ -94,7 +90,7 @@ cargo add mapfile_parser
|
|
94
90
|
Or add the following line manually to your `Cargo.toml` file:
|
95
91
|
|
96
92
|
```toml
|
97
|
-
mapfile_parser = "2.
|
93
|
+
mapfile_parser = "2.11.0"
|
98
94
|
```
|
99
95
|
|
100
96
|
## Versioning and changelog
|
@@ -36,7 +36,7 @@ If you use a `requirements.txt` file in your repository, then you can add
|
|
36
36
|
this library with the following line:
|
37
37
|
|
38
38
|
```txt
|
39
|
-
mapfile_parser>=2.
|
39
|
+
mapfile_parser>=2.11.0,<3.0.0
|
40
40
|
```
|
41
41
|
|
42
42
|
#### Development version
|
@@ -75,7 +75,7 @@ cargo add mapfile_parser
|
|
75
75
|
Or add the following line manually to your `Cargo.toml` file:
|
76
76
|
|
77
77
|
```toml
|
78
|
-
mapfile_parser = "2.
|
78
|
+
mapfile_parser = "2.11.0"
|
79
79
|
```
|
80
80
|
|
81
81
|
## Versioning and changelog
|
@@ -6,6 +6,7 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import argparse
|
9
|
+
from collections.abc import Callable
|
9
10
|
import decomp_settings
|
10
11
|
from pathlib import Path
|
11
12
|
|
@@ -13,14 +14,23 @@ from .. import mapfile
|
|
13
14
|
from .. import utils
|
14
15
|
|
15
16
|
|
16
|
-
def getComparison(
|
17
|
-
|
18
|
-
|
17
|
+
def getComparison(
|
18
|
+
mapPath: Path,
|
19
|
+
expectedMapPath: Path,
|
20
|
+
*,
|
21
|
+
reverseCheck: bool=True,
|
22
|
+
plfResolver: Callable[[Path], Path|None]|None=None,
|
23
|
+
plfResolverExpected: Callable[[Path], Path|None]|None=None,
|
24
|
+
) -> mapfile.MapsComparisonInfo:
|
25
|
+
buildMap = mapfile.MapFile.newFromMapFile(mapPath)
|
19
26
|
buildMap = buildMap.filterBySectionType(".bss")
|
27
|
+
if plfResolver is not None:
|
28
|
+
buildMap = buildMap.resolvePartiallyLinkedFiles(plfResolver)
|
20
29
|
|
21
|
-
expectedMap = mapfile.MapFile()
|
22
|
-
expectedMap.readMapFile(expectedMapPath)
|
30
|
+
expectedMap = mapfile.MapFile.newFromMapFile(expectedMapPath)
|
23
31
|
expectedMap = expectedMap.filterBySectionType(".bss")
|
32
|
+
if plfResolverExpected is not None:
|
33
|
+
expectedMap = expectedMap.resolvePartiallyLinkedFiles(plfResolverExpected)
|
24
34
|
|
25
35
|
return buildMap.compareFilesAndSymbols(expectedMap, checkOtherOnSelf=reverseCheck)
|
26
36
|
|
@@ -126,7 +136,15 @@ def printFileComparison(comparisonInfo: mapfile.MapsComparisonInfo):
|
|
126
136
|
utils.eprint("Some files appear to be missing symbols. Have they been renamed or declared as static? You may need to remake 'expected'")
|
127
137
|
|
128
138
|
|
129
|
-
def doBssCheck(
|
139
|
+
def doBssCheck(
|
140
|
+
mapPath: Path,
|
141
|
+
expectedMapPath: Path,
|
142
|
+
*,
|
143
|
+
printAll: bool=False,
|
144
|
+
reverseCheck: bool=True,
|
145
|
+
plfResolver: Callable[[Path], Path|None]|None=None,
|
146
|
+
plfResolverExpected: Callable[[Path], Path|None]|None=None,
|
147
|
+
) -> int:
|
130
148
|
if not mapPath.exists():
|
131
149
|
utils.eprint(f"{mapPath} must exist")
|
132
150
|
return 1
|
@@ -134,7 +152,7 @@ def doBssCheck(mapPath, expectedMapPath, *, printAll: bool=False, reverseCheck:
|
|
134
152
|
utils.eprint(f"{expectedMapPath} must exist")
|
135
153
|
return 1
|
136
154
|
|
137
|
-
comparisonInfo = getComparison(mapPath, expectedMapPath, reverseCheck=reverseCheck)
|
155
|
+
comparisonInfo = getComparison(mapPath, expectedMapPath, reverseCheck=reverseCheck, plfResolver=plfResolver, plfResolverExpected=plfResolverExpected)
|
138
156
|
printSymbolComparison(comparisonInfo, printAll)
|
139
157
|
|
140
158
|
if len(comparisonInfo.badFiles) + len(comparisonInfo.missingFiles) != 0:
|
@@ -165,8 +183,20 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
165
183
|
|
166
184
|
printAll: bool = args.print_all
|
167
185
|
reverseCheck: bool = not args.no_reverse_check
|
186
|
+
plfExt: list[str]|None = args.plf_ext
|
168
187
|
|
169
|
-
|
188
|
+
plfResolver = None
|
189
|
+
if plfExt is not None:
|
190
|
+
def resolver(x: Path) -> Path|None:
|
191
|
+
if x.suffix in plfExt:
|
192
|
+
newPath = x.with_suffix(".map")
|
193
|
+
if newPath.exists():
|
194
|
+
return newPath
|
195
|
+
return None
|
196
|
+
|
197
|
+
plfResolver = resolver
|
198
|
+
|
199
|
+
exit(doBssCheck(mapPath, expectedMapPath, printAll=printAll, reverseCheck=reverseCheck, plfResolver=plfResolver))
|
170
200
|
|
171
201
|
|
172
202
|
def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
|
@@ -193,4 +223,6 @@ def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser],
|
|
193
223
|
parser.add_argument("-a", "--print-all", help="Print all bss, not just non-matching.", action="store_true")
|
194
224
|
parser.add_argument("--no-reverse-check", help="Disable looking for symbols on the expected map that are missing on the built map file.", action="store_true")
|
195
225
|
|
226
|
+
parser.add_argument("-x", "--plf-ext", help="File extension for partially linked files (plf). Will be used to transform the `plf`s path into a mapfile path by replacing the extension. The extension must contain the leading period. This argument can be passed multiple times.", action="append")
|
227
|
+
|
196
228
|
parser.set_defaults(func=processArguments)
|
@@ -6,15 +6,28 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import argparse
|
9
|
+
from collections.abc import Callable
|
9
10
|
import decomp_settings
|
10
11
|
from pathlib import Path
|
11
|
-
from typing import
|
12
|
+
from typing import Literal
|
12
13
|
|
13
14
|
from .. import mapfile
|
14
15
|
from .. import utils
|
15
16
|
|
16
17
|
|
17
|
-
def doFirstDiff(
|
18
|
+
def doFirstDiff(
|
19
|
+
mapPath: Path,
|
20
|
+
expectedMapPath: Path,
|
21
|
+
romPath: Path,
|
22
|
+
expectedRomPath: Path,
|
23
|
+
diffCount: int=5,
|
24
|
+
mismatchSize: bool=False,
|
25
|
+
addColons: bool=True,
|
26
|
+
bytesConverterCallback: Callable[[bytes, mapfile.MapFile],str|None]|None=None,
|
27
|
+
endian: Literal["big", "little"] ="big",
|
28
|
+
plfResolver: Callable[[Path], Path|None]|None=None,
|
29
|
+
plfResolverExpected: Callable[[Path], Path|None]|None=None,
|
30
|
+
) -> int:
|
18
31
|
if not mapPath.exists():
|
19
32
|
print(f"{mapPath} must exist")
|
20
33
|
return 1
|
@@ -41,10 +54,13 @@ def doFirstDiff(mapPath, expectedMapPath, romPath, expectedRomPath, diffCount: i
|
|
41
54
|
print("No differences!")
|
42
55
|
return 0
|
43
56
|
|
44
|
-
builtMapFile = mapfile.MapFile()
|
45
|
-
|
46
|
-
|
47
|
-
|
57
|
+
builtMapFile = mapfile.MapFile.newFromMapFile(mapPath)
|
58
|
+
if plfResolver is not None:
|
59
|
+
builtMapFile = builtMapFile.resolvePartiallyLinkedFiles(plfResolver)
|
60
|
+
|
61
|
+
expectedMapFile = mapfile.MapFile.newFromMapFile(expectedMapPath)
|
62
|
+
if plfResolverExpected is not None:
|
63
|
+
expectedMapFile = expectedMapFile.resolvePartiallyLinkedFiles(plfResolverExpected)
|
48
64
|
|
49
65
|
endian_diff = 0
|
50
66
|
if endian == "little":
|
@@ -166,7 +182,20 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
166
182
|
|
167
183
|
endian = args.endian
|
168
184
|
|
169
|
-
|
185
|
+
plfExt: list[str]|None = args.plf_ext
|
186
|
+
|
187
|
+
plfResolver = None
|
188
|
+
if plfExt is not None:
|
189
|
+
def resolver(x: Path) -> Path|None:
|
190
|
+
if x.suffix in plfExt:
|
191
|
+
newPath = x.with_suffix(".map")
|
192
|
+
if newPath.exists():
|
193
|
+
return newPath
|
194
|
+
return None
|
195
|
+
|
196
|
+
plfResolver = resolver
|
197
|
+
|
198
|
+
exit(doFirstDiff(mapPath, expectedMapPath, romPath, expectedRomPath, diffCount, mismatchSize, endian=endian, plfResolver=plfResolver))
|
170
199
|
|
171
200
|
|
172
201
|
def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
|
@@ -200,4 +229,6 @@ def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser],
|
|
200
229
|
parser.add_argument("-m", "--mismatch-size", help="Do not exit early if the ROM sizes does not match", action="store_true")
|
201
230
|
parser.add_argument("-e", "--endian", help="Specify endianness of the binary", choices=["big", "little"], default="big")
|
202
231
|
|
232
|
+
parser.add_argument("-x", "--plf-ext", help="File extension for partially linked files (plf). Will be used to transform the `plf`s path into a mapfile path by replacing the extension. The extension must contain the leading period. This argument can be passed multiple times.", action="append")
|
233
|
+
|
203
234
|
parser.set_defaults(func=processArguments)
|
@@ -6,6 +6,7 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import argparse
|
9
|
+
from collections.abc import Callable
|
9
10
|
import decomp_settings
|
10
11
|
import json
|
11
12
|
from pathlib import Path
|
@@ -13,13 +14,20 @@ from pathlib import Path
|
|
13
14
|
from .. import mapfile
|
14
15
|
|
15
16
|
|
16
|
-
def doJsonify(
|
17
|
+
def doJsonify(
|
18
|
+
mapPath: Path,
|
19
|
+
outputPath: Path|None,
|
20
|
+
humanReadable: bool=True,
|
21
|
+
applyFixes: bool=False,
|
22
|
+
plfResolver: Callable[[Path], Path|None]|None=None,
|
23
|
+
) -> int:
|
17
24
|
if not mapPath.exists():
|
18
25
|
print(f"Could not find mapfile at '{mapPath}'")
|
19
26
|
return 1
|
20
27
|
|
21
|
-
mapFile = mapfile.MapFile()
|
22
|
-
|
28
|
+
mapFile = mapfile.MapFile.newFromMapFile(mapPath)
|
29
|
+
if plfResolver is not None:
|
30
|
+
mapFile = mapFile.resolvePartiallyLinkedFiles(plfResolver)
|
23
31
|
|
24
32
|
jsonStr = json.dumps(mapFile.toJson(humanReadable=humanReadable), indent=4)
|
25
33
|
|
@@ -44,8 +52,20 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
44
52
|
outputPath: Path|None = Path(args.output) if args.output is not None else None
|
45
53
|
machine: bool = args.machine
|
46
54
|
applyFixes: bool = args.apply_fixes
|
55
|
+
plfExt: list[str]|None = args.plf_ext
|
47
56
|
|
48
|
-
|
57
|
+
plfResolver = None
|
58
|
+
if plfExt is not None:
|
59
|
+
def resolver(x: Path) -> Path|None:
|
60
|
+
if x.suffix in plfExt:
|
61
|
+
newPath = x.with_suffix(".map")
|
62
|
+
if newPath.exists():
|
63
|
+
return newPath
|
64
|
+
return None
|
65
|
+
|
66
|
+
plfResolver = resolver
|
67
|
+
|
68
|
+
exit(doJsonify(mapPath, outputPath, humanReadable=not machine, applyFixes=applyFixes, plfResolver=plfResolver))
|
49
69
|
|
50
70
|
def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
|
51
71
|
parser = subparser.add_parser("jsonify", help="Converts a mapfile into a json format.")
|
@@ -67,4 +87,6 @@ def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser],
|
|
67
87
|
parser.add_argument("-m", "--machine", help="Emit numbers as numbers instead of outputting them as pretty strings.", action="store_true")
|
68
88
|
parser.add_argument("-f", "--apply-fixes", help="DEPRECATED, this is applied automatically now. Apply certain fixups, like fixing size calculation of because of the existence of fake `.NON_MATCHING` symbols.", action="store_true")
|
69
89
|
|
90
|
+
parser.add_argument("-x", "--plf-ext", help="File extension for partially linked files (plf). Will be used to transform the `plf`s path into a mapfile path by replacing the extension. The extension must contain the leading period. This argument can be passed multiple times.", action="append")
|
91
|
+
|
70
92
|
parser.set_defaults(func=processArguments)
|
{mapfile_parser-2.9.4 → mapfile_parser-2.11.0}/src/mapfile_parser/frontends/objdiff_report.py
RENAMED
@@ -6,6 +6,7 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import argparse
|
9
|
+
from collections.abc import Callable
|
9
10
|
import dataclasses
|
10
11
|
import decomp_settings
|
11
12
|
from pathlib import Path
|
@@ -34,13 +35,15 @@ def doObjdiffReport(
|
|
34
35
|
emitCategories: bool=False,
|
35
36
|
quiet: bool=False,
|
36
37
|
summaryTableConfig: SummaryTableConfig|None=SummaryTableConfig(),
|
38
|
+
plfResolver: Callable[[Path], Path|None]|None=None,
|
37
39
|
) -> int:
|
38
40
|
if not mapPath.exists():
|
39
41
|
print(f"Could not find mapfile at '{mapPath}'")
|
40
42
|
return 1
|
41
43
|
|
42
|
-
mapFile = mapfile.MapFile()
|
43
|
-
|
44
|
+
mapFile = mapfile.MapFile.newFromMapFile(mapPath)
|
45
|
+
if plfResolver is not None:
|
46
|
+
mapFile = mapFile.resolvePartiallyLinkedFiles(plfResolver)
|
44
47
|
|
45
48
|
if emitCategories:
|
46
49
|
printDefaultCategories(mapFile, prefixesToTrim)
|
@@ -244,7 +247,11 @@ tools:
|
|
244
247
|
mapfile_parser:
|
245
248
|
progress_report:
|
246
249
|
# output: report.json # Optional
|
247
|
-
|
250
|
+
# If you don't have .NON_MATCHING markers in all your function and data
|
251
|
+
# symbols then you should set `check_asm_paths: True` and
|
252
|
+
# `report_data: False`, otherwise those progress will get a fake boost.
|
253
|
+
check_asm_paths: False
|
254
|
+
report_data: True
|
248
255
|
# Change if the asm path in the build folder is deeper than two subfolders.
|
249
256
|
# i.e.: "build/us/asm/header.o" -> `path_index: 3`.
|
250
257
|
# i.e.: "build/us/asm/us/header.o" -> `path_index: 4`.
|
@@ -274,6 +281,12 @@ tools:
|
|
274
281
|
- {p}
|
275
282
|
""", end="")
|
276
283
|
|
284
|
+
print(" # The following categories are autogenerated and they are intended as a")
|
285
|
+
print(" # guide and examples on how to setup your own categories. Please don't")
|
286
|
+
print(" # commit them as-is.")
|
287
|
+
print()
|
288
|
+
print(" # List of categories. `id`s must be unique, but each path may be")
|
289
|
+
print(" # duplicated across categories.")
|
277
290
|
print(" categories:")
|
278
291
|
print(" # Categories by path")
|
279
292
|
printCategories(categoriesByPath)
|
@@ -310,6 +323,7 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
310
323
|
pathIndex = int(args.path_index)
|
311
324
|
else:
|
312
325
|
pathIndex = pathIndexDefault
|
326
|
+
reportCategories.setReportData(settings.reportData)
|
313
327
|
else:
|
314
328
|
outputPath = args.output
|
315
329
|
if args.prefixes_to_trim is not None:
|
@@ -317,6 +331,7 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
317
331
|
else:
|
318
332
|
prefixesToTrim = []
|
319
333
|
pathIndex = int(args.path_index) if args.path_index is not None else pathIndexDefault
|
334
|
+
reportCategories.setReportData(False)
|
320
335
|
|
321
336
|
if decompConfig is not None:
|
322
337
|
version = decompConfig.get_version_by_name(args.version)
|
@@ -347,6 +362,18 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
347
362
|
else:
|
348
363
|
summaryTableConfig = None
|
349
364
|
|
365
|
+
plfExt: list[str]|None = args.plf_ext
|
366
|
+
|
367
|
+
plfResolver = None
|
368
|
+
if plfExt is not None:
|
369
|
+
def resolver(x: Path) -> Path|None:
|
370
|
+
if x.suffix in plfExt:
|
371
|
+
newPath = x.with_suffix(".map")
|
372
|
+
if newPath.exists():
|
373
|
+
return newPath
|
374
|
+
return None
|
375
|
+
plfResolver = resolver
|
376
|
+
|
350
377
|
exit(doObjdiffReport(
|
351
378
|
mapPath,
|
352
379
|
outputPath,
|
@@ -357,6 +384,7 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
357
384
|
nonmatchingsPath=nonmatchingsPath,
|
358
385
|
emitCategories=emitCategories,
|
359
386
|
summaryTableConfig=summaryTableConfig,
|
387
|
+
plfResolver=plfResolver,
|
360
388
|
))
|
361
389
|
|
362
390
|
def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
|
@@ -386,7 +414,8 @@ tools:
|
|
386
414
|
mapfile_parser:
|
387
415
|
progress_report:
|
388
416
|
# output: report.json # Optional
|
389
|
-
check_asm_paths:
|
417
|
+
check_asm_paths: False
|
418
|
+
report_data: True
|
390
419
|
# path_index: 2
|
391
420
|
# List of build prefixes to trim from each object file
|
392
421
|
prefixes_to_trim:
|
@@ -468,6 +497,8 @@ tools:
|
|
468
497
|
parser.add_argument("--emit-categories", help="Print automatically-generated categories from your mapfile, using the decomp.yaml format. These categories are expected to be tweaked and not used as-is.", action="store_true")
|
469
498
|
parser.add_argument("--quiet", help="Avoid printing the progress report to the stdout and to the Github action summary.", action="store_true")
|
470
499
|
|
500
|
+
parser.add_argument("-x", "--plf-ext", help="File extension for partially linked files (plf). Will be used to transform the `plf`s path into a mapfile path by replacing the extension. The extension must contain the leading period. This argument can be passed multiple times.", action="append")
|
501
|
+
|
471
502
|
parser.set_defaults(func=processArguments)
|
472
503
|
|
473
504
|
|
@@ -478,6 +509,7 @@ class SpecificSettings:
|
|
478
509
|
categories: list[Category]
|
479
510
|
pathIndex: int|None
|
480
511
|
checkAsmPaths: bool
|
512
|
+
reportData: bool
|
481
513
|
|
482
514
|
@staticmethod
|
483
515
|
def fromDecompConfig(decompConfig: decomp_settings.Config|None=None) -> SpecificSettings|None:
|
@@ -489,6 +521,7 @@ class SpecificSettings:
|
|
489
521
|
categories: list[Category] = []
|
490
522
|
pathIndex: int|None = None
|
491
523
|
checkAsmPaths: bool = False
|
524
|
+
reportData = False
|
492
525
|
if decompConfig.tools is not None:
|
493
526
|
mapfileParserConfig = decompConfig.tools.get("mapfile_parser")
|
494
527
|
if mapfileParserConfig is not None:
|
@@ -512,6 +545,7 @@ class SpecificSettings:
|
|
512
545
|
if var is not None:
|
513
546
|
pathIndex = var
|
514
547
|
checkAsmPaths = bool(raw.get("check_asm_paths", False))
|
548
|
+
reportData = bool(raw.get("report_data", False))
|
515
549
|
|
516
550
|
return SpecificSettings(
|
517
551
|
output,
|
@@ -519,6 +553,7 @@ class SpecificSettings:
|
|
519
553
|
categories,
|
520
554
|
pathIndex,
|
521
555
|
checkAsmPaths,
|
556
|
+
reportData,
|
522
557
|
)
|
523
558
|
|
524
559
|
@dataclasses.dataclass
|
@@ -6,6 +6,7 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import argparse
|
9
|
+
from collections.abc import Callable
|
9
10
|
import decomp_settings
|
10
11
|
from pathlib import Path
|
11
12
|
from typing import TextIO
|
@@ -21,13 +22,18 @@ def writePj64SymsToFile(mapFile: mapfile.MapFile, outFile: TextIO):
|
|
21
22
|
symType = "code" if file.sectionType == ".text" else "data"
|
22
23
|
outFile.write(f"{sym.vram:08X},{symType},{sym.name}\n")
|
23
24
|
|
24
|
-
def doPj64Syms(
|
25
|
+
def doPj64Syms(
|
26
|
+
mapPath: Path,
|
27
|
+
outputPath: Path|None,
|
28
|
+
plfResolver: Callable[[Path], Path|None]|None=None,
|
29
|
+
) -> int:
|
25
30
|
if not mapPath.exists():
|
26
31
|
print(f"Could not find mapfile at '{mapPath}'")
|
27
32
|
return 1
|
28
33
|
|
29
|
-
mapFile = mapfile.MapFile()
|
30
|
-
|
34
|
+
mapFile = mapfile.MapFile.newFromMapFile(mapPath)
|
35
|
+
if plfResolver is not None:
|
36
|
+
mapFile = mapFile.resolvePartiallyLinkedFiles(plfResolver)
|
31
37
|
|
32
38
|
if outputPath is None:
|
33
39
|
writePj64SymsToFile(mapFile, sys.stdout)
|
@@ -48,7 +54,20 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
48
54
|
|
49
55
|
outputPath: Path = args.output
|
50
56
|
|
51
|
-
|
57
|
+
plfExt: list[str]|None = args.plf_ext
|
58
|
+
|
59
|
+
plfResolver = None
|
60
|
+
if plfExt is not None:
|
61
|
+
def resolver(x: Path) -> Path|None:
|
62
|
+
if x.suffix in plfExt:
|
63
|
+
newPath = x.with_suffix(".map")
|
64
|
+
if newPath.exists():
|
65
|
+
return newPath
|
66
|
+
return None
|
67
|
+
|
68
|
+
plfResolver = resolver
|
69
|
+
|
70
|
+
exit(doPj64Syms(mapPath, outputPath, plfResolver=plfResolver))
|
52
71
|
|
53
72
|
def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
|
54
73
|
parser = subparser.add_parser("pj64_syms", help="Produce a PJ64 compatible symbol map.")
|
@@ -68,4 +87,6 @@ def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser],
|
|
68
87
|
|
69
88
|
parser.add_argument("output", help="Path to output file. If omitted then output will be written to stdout", type=Path, nargs="?")
|
70
89
|
|
90
|
+
parser.add_argument("-x", "--plf-ext", help="File extension for partially linked files (plf). Will be used to transform the `plf`s path into a mapfile path by replacing the extension. The extension must contain the leading period. This argument can be passed multiple times.", action="append")
|
91
|
+
|
71
92
|
parser.set_defaults(func=processArguments)
|
@@ -6,6 +6,7 @@
|
|
6
6
|
from __future__ import annotations
|
7
7
|
|
8
8
|
import argparse
|
9
|
+
from collections.abc import Callable
|
9
10
|
import decomp_settings
|
10
11
|
import json
|
11
12
|
from pathlib import Path
|
@@ -14,20 +15,37 @@ from .. import mapfile
|
|
14
15
|
from .. import progress_stats
|
15
16
|
|
16
17
|
|
17
|
-
def getProgress(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
def getProgress(
|
19
|
+
mapPath: Path,
|
20
|
+
asmPath: Path,
|
21
|
+
nonmatchingsPath: Path,
|
22
|
+
pathIndex: int=2,
|
23
|
+
checkFunctionFiles: bool=True,
|
24
|
+
debugging: bool=False,
|
25
|
+
plfResolver: Callable[[Path], Path|None]|None=None,
|
26
|
+
) -> tuple[progress_stats.ProgressStats, dict[str, progress_stats.ProgressStats]]:
|
27
|
+
mapFile = mapfile.MapFile.newFromMapFile(mapPath)
|
28
|
+
mapFile.filterBySectionType(".text")
|
29
|
+
if plfResolver is not None:
|
30
|
+
mapFile = mapFile.resolvePartiallyLinkedFiles(plfResolver)
|
31
|
+
|
32
|
+
return mapFile.getProgress(asmPath, nonmatchingsPath, pathIndex=pathIndex, checkFunctionFiles=checkFunctionFiles)
|
33
|
+
|
34
|
+
def doProgress(
|
35
|
+
mapPath: Path,
|
36
|
+
asmPath: Path,
|
37
|
+
nonmatchingsPath: Path,
|
38
|
+
pathIndex: int=2,
|
39
|
+
checkFunctionFiles: bool=True,
|
40
|
+
print_json: bool=False,
|
41
|
+
debugging: bool=False,
|
42
|
+
plfResolver: Callable[[Path], Path|None]|None=None,
|
43
|
+
) -> int:
|
26
44
|
if not mapPath.exists():
|
27
45
|
print(f"Could not find mapfile at '{mapPath}'")
|
28
46
|
return 1
|
29
47
|
|
30
|
-
totalStats, progressPerFolder = getProgress(mapPath, asmPath, nonmatchingsPath, pathIndex=pathIndex, checkFunctionFiles=checkFunctionFiles, debugging=debugging)
|
48
|
+
totalStats, progressPerFolder = getProgress(mapPath, asmPath, nonmatchingsPath, pathIndex=pathIndex, checkFunctionFiles=checkFunctionFiles, debugging=debugging, plfResolver=plfResolver)
|
31
49
|
|
32
50
|
if print_json:
|
33
51
|
json_temp: dict[str, dict[str, int|float]] = {
|
@@ -59,7 +77,20 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
|
|
59
77
|
debugging: bool = args.debugging #! @deprecated
|
60
78
|
print_json: bool = args.json
|
61
79
|
|
62
|
-
|
80
|
+
plfExt: list[str]|None = args.plf_ext
|
81
|
+
|
82
|
+
plfResolver = None
|
83
|
+
if plfExt is not None:
|
84
|
+
def resolver(x: Path) -> Path|None:
|
85
|
+
if x.suffix in plfExt:
|
86
|
+
newPath = x.with_suffix(".map")
|
87
|
+
if newPath.exists():
|
88
|
+
return newPath
|
89
|
+
return None
|
90
|
+
|
91
|
+
plfResolver = resolver
|
92
|
+
|
93
|
+
exit(doProgress(mapPath, asmPath, nonmatchingsPath, pathIndex=pathIndex, checkFunctionFiles=checkFunctionFiles, print_json=print_json, debugging=debugging, plfResolver=plfResolver))
|
63
94
|
|
64
95
|
def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
|
65
96
|
parser = subparser.add_parser("progress", help="Computes current progress of the matched functions. Relies on a splat (https://github.com/ethteck/splat) folder structure and matched functions not longer having a file.")
|
@@ -92,4 +123,6 @@ def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser],
|
|
92
123
|
parser.add_argument("-d", "--debugging", help="Enable debugging prints. This option is deprecated", action="store_true")
|
93
124
|
parser.add_argument("-j", "--json", help="Print the stats as json instead of a human readable format.", action="store_true")
|
94
125
|
|
126
|
+
parser.add_argument("-x", "--plf-ext", help="File extension for partially linked files (plf). Will be used to transform the `plf`s path into a mapfile path by replacing the extension. The extension must contain the leading period. This argument can be passed multiple times.", action="append")
|
127
|
+
|
95
128
|
parser.set_defaults(func=processArguments)
|