mapfile-parser 2.9.4__cp39-cp39-musllinux_1_2_armv7l.whl → 2.10.0__cp39-cp39-musllinux_1_2_armv7l.whl

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.
@@ -5,7 +5,7 @@
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
- __version_info__ = (2, 9, 4)
8
+ __version_info__ = (2, 10, 0)
9
9
  __version__ = ".".join(map(str, __version_info__)) # + "-dev0"
10
10
  __author__ = "Decompollaborate"
11
11
 
@@ -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(mapPath, expectedMapPath, *, reverseCheck: bool=True) -> mapfile.MapsComparisonInfo:
17
- buildMap = mapfile.MapFile()
18
- buildMap.readMapFile(mapPath)
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(mapPath, expectedMapPath, *, printAll: bool=False, reverseCheck: bool=True) -> int:
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
- exit(doBssCheck(mapPath, expectedMapPath, printAll=printAll, reverseCheck=reverseCheck))
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 Callable, Literal
12
+ from typing import Literal
12
13
 
13
14
  from .. import mapfile
14
15
  from .. import utils
15
16
 
16
17
 
17
- def doFirstDiff(mapPath, expectedMapPath, romPath, expectedRomPath, diffCount: int=5, mismatchSize: bool=False, addColons: bool=True, bytesConverterCallback:Callable[[bytes, mapfile.MapFile],str|None]|None=None, endian: Literal["big", "little"] ="big") -> int:
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
- builtMapFile.readMapFile(mapPath)
46
- expectedMapFile = mapfile.MapFile()
47
- expectedMapFile.readMapFile(expectedMapPath)
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
- exit(doFirstDiff(mapPath, expectedMapPath, romPath, expectedRomPath, diffCount, mismatchSize, endian=endian))
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(mapPath: Path, outputPath: Path|None, humanReadable: bool=True, applyFixes: bool=False) -> int:
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
- mapFile.readMapFile(mapPath)
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
- exit(doJsonify(mapPath, outputPath, humanReadable=not machine, applyFixes=applyFixes))
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)
@@ -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
- mapFile.readMapFile(mapPath)
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)
@@ -347,6 +350,18 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
347
350
  else:
348
351
  summaryTableConfig = None
349
352
 
353
+ plfExt: list[str]|None = args.plf_ext
354
+
355
+ plfResolver = None
356
+ if plfExt is not None:
357
+ def resolver(x: Path) -> Path|None:
358
+ if x.suffix in plfExt:
359
+ newPath = x.with_suffix(".map")
360
+ if newPath.exists():
361
+ return newPath
362
+ return None
363
+ plfResolver = resolver
364
+
350
365
  exit(doObjdiffReport(
351
366
  mapPath,
352
367
  outputPath,
@@ -357,6 +372,7 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
357
372
  nonmatchingsPath=nonmatchingsPath,
358
373
  emitCategories=emitCategories,
359
374
  summaryTableConfig=summaryTableConfig,
375
+ plfResolver=plfResolver,
360
376
  ))
361
377
 
362
378
  def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
@@ -468,6 +484,8 @@ tools:
468
484
  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
485
  parser.add_argument("--quiet", help="Avoid printing the progress report to the stdout and to the Github action summary.", action="store_true")
470
486
 
487
+ 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")
488
+
471
489
  parser.set_defaults(func=processArguments)
472
490
 
473
491
 
@@ -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(mapPath: Path, outputPath: Path|None) -> int:
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
- mapFile.readMapFile(mapPath)
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
- exit(doPj64Syms(mapPath, outputPath))
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(mapPath: Path, asmPath: Path, nonmatchingsPath: Path, pathIndex: int=2, checkFunctionFiles: bool=True, debugging: bool=False) -> tuple[progress_stats.ProgressStats, dict[str, progress_stats.ProgressStats]]:
18
- mapFile = mapfile.MapFile()
19
-
20
- mapFile.debugging = debugging
21
- mapFile.readMapFile(mapPath)
22
-
23
- return mapFile.filterBySectionType(".text").getProgress(asmPath, nonmatchingsPath, pathIndex=pathIndex, checkFunctionFiles=checkFunctionFiles)
24
-
25
- def doProgress(mapPath: Path, asmPath: Path, nonmatchingsPath: Path, pathIndex: int=2, checkFunctionFiles: bool=True, print_json: bool=False, debugging: bool=False) -> int:
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
- exit(doProgress(mapPath, asmPath, nonmatchingsPath, pathIndex=pathIndex, checkFunctionFiles=checkFunctionFiles, print_json=print_json, debugging=debugging))
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)
@@ -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,13 +14,22 @@ from .. import mapfile
13
14
  from .. import utils
14
15
 
15
16
 
16
- def doSymInfo(mapPath: Path, symName: str, *, as_vram: bool=False, as_vrom: bool=False, as_name: bool=False) -> int:
17
+ def doSymInfo(
18
+ mapPath: Path,
19
+ symName: str,
20
+ *,
21
+ as_vram: bool=False,
22
+ as_vrom: bool=False,
23
+ as_name: bool=False,
24
+ plfResolver: Callable[[Path], Path|None]|None=None,
25
+ ) -> int:
17
26
  if not mapPath.exists():
18
27
  print(f"Could not find mapfile at '{mapPath}'")
19
28
  return 1
20
29
 
21
- mapFile = mapfile.MapFile()
22
- mapFile.readMapFile(mapPath)
30
+ mapFile = mapfile.MapFile.newFromMapFile(mapPath)
31
+ if plfResolver is not None:
32
+ mapFile = mapFile.resolvePartiallyLinkedFiles(plfResolver)
23
33
 
24
34
  possibleFiles: list[mapfile.Section] = []
25
35
 
@@ -66,8 +76,20 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
66
76
  as_vram: bool = args.vram
67
77
  as_vrom: bool = args.vrom
68
78
  as_name: bool = args.name
79
+ plfExt: list[str]|None = args.plf_ext
69
80
 
70
- exit(doSymInfo(mapPath, symName, as_vram=as_vram, as_vrom=as_vrom, as_name=as_name))
81
+ plfResolver = None
82
+ if plfExt is not None:
83
+ def resolver(x: Path) -> Path|None:
84
+ if x.suffix in plfExt:
85
+ newPath = x.with_suffix(".map")
86
+ if newPath.exists():
87
+ return newPath
88
+ return None
89
+
90
+ plfResolver = resolver
91
+
92
+ exit(doSymInfo(mapPath, symName, as_vram=as_vram, as_vrom=as_vrom, as_name=as_name, plfResolver=plfResolver))
71
93
 
72
94
  def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
73
95
  parser = subparser.add_parser("sym_info", help="Display various information about a symbol or address.")
@@ -86,6 +108,8 @@ def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser],
86
108
  parser.add_argument("mapfile", help="Path to a map file.", type=Path)
87
109
  parser.add_argument("symname", help="Symbol name or VROM/VRAM address to lookup. How to treat this argument will be guessed.")
88
110
 
111
+ 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")
112
+
89
113
  vram_vrom_group = parser.add_mutually_exclusive_group()
90
114
  vram_vrom_group.add_argument("--vram", help="Treat the argument as a VRAM address instead of guessing.", action="store_true")
91
115
  vram_vrom_group.add_argument("--vrom", help="Treat the argument as a VROM address instead of guessing.", action="store_true")
@@ -6,19 +6,29 @@
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
 
12
13
  from .. import mapfile
13
14
 
14
15
 
15
- def doSymbolSizesCsv(mapPath: Path, outputPath: Path|None, filterSection: str|None=None, sameFolder: bool=False, symbolsSummary: bool=False, allFiles: bool=False) -> int:
16
+ def doSymbolSizesCsv(
17
+ mapPath: Path,
18
+ outputPath: Path|None,
19
+ filterSection: str|None=None,
20
+ sameFolder: bool=False,
21
+ symbolsSummary: bool=False,
22
+ allFiles: bool=False,
23
+ plfResolver: Callable[[Path], Path|None]|None=None,
24
+ ) -> int:
16
25
  if not mapPath.exists():
17
26
  print(f"Could not find mapfile at '{mapPath}'")
18
27
  return 1
19
28
 
20
- mapFile = mapfile.MapFile()
21
- mapFile.readMapFile(mapPath)
29
+ mapFile = mapfile.MapFile.newFromMapFile(mapPath)
30
+ if plfResolver is not None:
31
+ mapFile = mapFile.resolvePartiallyLinkedFiles(plfResolver)
22
32
 
23
33
  if filterSection is not None:
24
34
  mapFile = mapFile.filterBySectionType(filterSection)
@@ -53,8 +63,20 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
53
63
  sameFolder: bool = args.same_folder
54
64
  symbolsSummary: bool = args.symbols
55
65
  allFiles: bool = args.all
66
+ plfExt: list[str]|None = args.plf_ext
56
67
 
57
- exit(doSymbolSizesCsv(mapPath, outputPath, filterSection, sameFolder, symbolsSummary, allFiles))
68
+ plfResolver = None
69
+ if plfExt is not None:
70
+ def resolver(x: Path) -> Path|None:
71
+ if x.suffix in plfExt:
72
+ newPath = x.with_suffix(".map")
73
+ if newPath.exists():
74
+ return newPath
75
+ return None
76
+
77
+ plfResolver = resolver
78
+
79
+ exit(doSymbolSizesCsv(mapPath, outputPath, filterSection, sameFolder, symbolsSummary, allFiles, plfResolver=plfResolver))
58
80
 
59
81
  def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
60
82
  parser = subparser.add_parser("symbol_sizes_csv", help="Produces a csv summarizing the files sizes by parsing a map file.")
@@ -78,4 +100,6 @@ def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser],
78
100
  parser.add_argument("-a", "--all", help="Don't skip files without symbols.", action="store_true")
79
101
  parser.add_argument("-f", "--filter-section", help="Only print the symbols of the passed section. For example: .text")
80
102
 
103
+ 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")
104
+
81
105
  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
  from pathlib import Path
11
12
  import requests # type: ignore
@@ -55,12 +56,25 @@ def uploadEntriesToFrogress(entries: dict[str, int], category: str, url: str, ap
55
56
  return 0
56
57
 
57
58
 
58
- def doUploadFrogress(mapPath: Path, asmPath: Path, nonmatchingsPath: Path, project: str, version: str, category: str, baseurl: str, apikey: str|None=None, verbose: bool=False, checkFunctionFiles: bool=True, dryRun: bool=False) -> int:
59
+ def doUploadFrogress(
60
+ mapPath: Path,
61
+ asmPath: Path,
62
+ nonmatchingsPath: Path,
63
+ project: str,
64
+ version: str,
65
+ category: str,
66
+ baseurl: str,
67
+ apikey: str|None=None,
68
+ verbose: bool=False,
69
+ checkFunctionFiles: bool=True,
70
+ dryRun: bool=False,
71
+ plfResolver: Callable[[Path], Path|None]|None=None,
72
+ ) -> int:
59
73
  if not mapPath.exists():
60
74
  print(f"Could not find mapfile at '{mapPath}'")
61
75
  return 1
62
76
 
63
- totalStats, progressPerFolder = progress.getProgress(mapPath, asmPath, nonmatchingsPath, checkFunctionFiles=checkFunctionFiles)
77
+ totalStats, progressPerFolder = progress.getProgress(mapPath, asmPath, nonmatchingsPath, checkFunctionFiles=checkFunctionFiles, plfResolver=plfResolver)
64
78
 
65
79
  entries: dict[str, int] = getFrogressEntriesFromStats(totalStats, progressPerFolder, verbose)
66
80
 
@@ -89,8 +103,20 @@ def processArguments(args: argparse.Namespace, decompConfig: decomp_settings.Con
89
103
  verbose: bool = args.verbose
90
104
  checkFunctionFiles: bool = not args.avoid_function_files
91
105
  dryRun: bool = args.dry_run
106
+ plfExt: list[str]|None = args.plf_ext
92
107
 
93
- exit(doUploadFrogress(mapPath, asmPath, nonmatchingsPath, project, version, category, baseurl, apikey, verbose, checkFunctionFiles, dryRun=dryRun))
108
+ plfResolver = None
109
+ if plfExt is not None:
110
+ def resolver(x: Path) -> Path|None:
111
+ if x.suffix in plfExt:
112
+ newPath = x.with_suffix(".map")
113
+ if newPath.exists():
114
+ return newPath
115
+ return None
116
+
117
+ plfResolver = resolver
118
+
119
+ exit(doUploadFrogress(mapPath, asmPath, nonmatchingsPath, project, version, category, baseurl, apikey, verbose, checkFunctionFiles, dryRun=dryRun, plfResolver=plfResolver))
94
120
 
95
121
  def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser], decompConfig: decomp_settings.Config|None=None):
96
122
  parser = subparser.add_parser("upload_frogress", help="Uploads current progress of the matched functions to frogress (https://github.com/decompals/frogress).")
@@ -132,4 +158,6 @@ def addSubparser(subparser: argparse._SubParsersAction[argparse.ArgumentParser],
132
158
  parser.add_argument("-f", "--avoid-function-files", help="Avoid checking if the assembly file for a function exists as a way to determine if the function has been matched or not", action="store_true")
133
159
  parser.add_argument("-d", "--dry-run", help="Stop before uploading the progress.", action="store_true")
134
160
 
161
+ 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")
162
+
135
163
  parser.set_defaults(func=processArguments)
mapfile_parser/mapfile.py CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ from collections.abc import Callable
8
9
  import dataclasses
9
10
  import re
10
11
  from typing import Any, Generator
@@ -159,7 +160,7 @@ class Symbol:
159
160
 
160
161
 
161
162
  def clone(self) -> Symbol:
162
- return Symbol(self.name, self.vram, self.size, self.vrom, self.align)
163
+ return Symbol(self.name, self.vram, self.size, self.vrom, self.align, self.nonmatchingSymExists)
163
164
 
164
165
 
165
166
  def __eq__(self, other: object) -> bool:
@@ -377,7 +378,7 @@ class Section:
377
378
 
378
379
 
379
380
  def clone(self) -> Section:
380
- f = Section(self.filepath, self.vram, self.size, self.sectionType, self.vrom, self.align)
381
+ f = Section(self.filepath, self.vram, self.size, self.sectionType, self.vrom, self.align, self.isFill)
381
382
  for sym in self._symbols:
382
383
  f._symbols.append(sym.clone())
383
384
  return f
@@ -449,7 +450,7 @@ class Segment:
449
450
  newSegment._sectionsList.append(section)
450
451
  return newSegment
451
452
 
452
- #! @deprecated: Use either `getEverySectionExceptSectionType` instead.
453
+ #! @deprecated: Use `getEverySectionExceptSectionType` instead.
453
454
  def getEveryFileExceptSectionType(self, sectionType: str) -> Segment:
454
455
  return self.getEverySectionExceptSectionType(sectionType)
455
456
 
@@ -588,28 +589,31 @@ class Segment:
588
589
  self._sectionsList.append(section)
589
590
 
590
591
 
591
- #! @deprecated: Use either `copySectionList` instead.
592
+ #! @deprecated: Use `copySectionList` instead.
592
593
  def copyFileList(self) -> list[Section]:
593
594
  """Returns a copy (not a reference) of the internal section list"""
594
595
  return self.copySectionList()
595
596
 
596
- #! @deprecated: Use either `setSectionList` instead.
597
+ #! @deprecated: Use `setSectionList` instead.
597
598
  def setFileList(self, newList: list[Section]) -> None:
598
599
  """Replaces the internal section list with a copy of `newList`"""
599
600
  return self.setSectionList(newList)
600
601
 
601
- #! @deprecated: Use either `appendSection` instead.
602
+ #! @deprecated: Use `appendSection` instead.
602
603
  def appendFile(self, section: Section) -> None:
603
604
  """Appends a copy of `section` into the internal section list"""
604
605
  return self.appendSection(section)
605
606
 
606
607
 
607
608
  def clone(self) -> Segment:
608
- s = Segment(self.name, self.vram, self.size, self.vrom, self.align)
609
+ s = self.cloneNoSectionlist()
609
610
  for f in self._sectionsList:
610
611
  s._sectionsList.append(f.clone())
611
612
  return s
612
613
 
614
+ def cloneNoSectionlist(self) -> Segment:
615
+ return Segment(self.name, self.vram, self.size, self.vrom, self.align)
616
+
613
617
 
614
618
  def __iter__(self) -> Generator[Section, None, None]:
615
619
  for section in self._sectionsList:
@@ -706,7 +710,7 @@ class MapFile:
706
710
 
707
711
  return nativeMapFile
708
712
 
709
- #! @deprecated: Use either `newFromMapFile` instead.
713
+ #! @deprecated: Use `newFromMapFile` instead.
710
714
  def readMapFile(self, mapPath: Path):
711
715
  """
712
716
  Opens the mapfile pointed by the `mapPath` argument and parses it.
@@ -719,12 +723,11 @@ class MapFile:
719
723
  - Metrowerks ld
720
724
  """
721
725
 
722
- nativeMapFile = MapFileRs()
723
- nativeMapFile.readMapFile(mapPath)
726
+ nativeMapFile = MapFileRs.newFromMapFile(mapPath)
724
727
 
725
728
  self._transferContentsFromNativeMapFile(nativeMapFile)
726
729
 
727
- #! @deprecated: Use either `newFromMapStr` instead.
730
+ #! @deprecated: Use `newFromMapStr` instead.
728
731
  def parseMapContents(self, mapContents: str):
729
732
  """
730
733
  Parses the contents of the map.
@@ -739,12 +742,11 @@ class MapFile:
739
742
  - Metrowerks ld
740
743
  """
741
744
 
742
- nativeMapFile = MapFileRs()
743
- nativeMapFile.parseMapContents(mapContents)
745
+ nativeMapFile = MapFileRs.newFromMapStr(mapContents)
744
746
 
745
747
  self._transferContentsFromNativeMapFile(nativeMapFile)
746
748
 
747
- #! @deprecated: Use either `newFromGnuMapStr` instead.
749
+ #! @deprecated: Use `newFromGnuMapStr` instead.
748
750
  def parseMapContentsGNU(self, mapContents: str):
749
751
  """
750
752
  Parses the contents of a GNU ld map.
@@ -752,12 +754,11 @@ class MapFile:
752
754
  The `mapContents` argument must contain the contents of a GNU ld mapfile.
753
755
  """
754
756
 
755
- nativeMapFile = MapFileRs()
756
- nativeMapFile.parseMapContentsGNU(mapContents)
757
+ nativeMapFile = MapFileRs.newFromGnuMapStr(mapContents)
757
758
 
758
759
  self._transferContentsFromNativeMapFile(nativeMapFile)
759
760
 
760
- #! @deprecated: Use either `newFromLldMapStr` instead.
761
+ #! @deprecated: Use `newFromLldMapStr` instead.
761
762
  def parseMapContentsLLD(self, mapContents: str):
762
763
  """
763
764
  Parses the contents of a clang ld.lld map.
@@ -765,8 +766,7 @@ class MapFile:
765
766
  The `mapContents` argument must contain the contents of a clang ld.lld mapfile.
766
767
  """
767
768
 
768
- nativeMapFile = MapFileRs()
769
- nativeMapFile.parseMapContentsLLD(mapContents)
769
+ nativeMapFile = MapFileRs.newFromLldMapStr(mapContents)
770
770
 
771
771
  self._transferContentsFromNativeMapFile(nativeMapFile)
772
772
 
@@ -1015,6 +1015,86 @@ class MapFile:
1015
1015
 
1016
1016
  return compInfo
1017
1017
 
1018
+ def resolvePartiallyLinkedFiles(self, resolver: Callable[[Path], Path|None]) -> MapFile:
1019
+ """
1020
+ Resolve sections and paths of a mapfile built from partially linked objects.
1021
+
1022
+ `elf` files built by using partially linked files/objects (usually
1023
+ referred to as `plf`) usually generate mapfiles that have filepaths that
1024
+ point to the partially linked objects instead of the original objects
1025
+ used to build those intermediary objects, making it awkward to work with
1026
+ paths because all symbols will be listed as part as the same single `plf`.
1027
+
1028
+ This function resolves those sections by using a resolver callback that
1029
+ transforms a path to an object/`plf` into the corresponding mapfile of
1030
+ said partially linked object.
1031
+ This callback should return `None` if the given path does not correspond
1032
+ to a `plf`, the pointed mapfile does not exist, etc.
1033
+
1034
+ An usual convention for a file extension for partially linked objects is
1035
+ the `.plf` extension instead of `.o`.
1036
+ """
1037
+
1038
+ # Construct a mapping for every "plf -> map"
1039
+ knownMaps: dict[Path, MapFile] = dict()
1040
+ for seg in self._segmentsList:
1041
+ for sect in seg._sectionsList:
1042
+ # Only read the map if this is a new plf.
1043
+ if sect.filepath in knownMaps:
1044
+ continue
1045
+ if (other_map_path := resolver(sect.filepath)) is not None:
1046
+ knownMaps[sect.filepath] = MapFile.newFromMapFile(other_map_path)
1047
+ return self._resolve_plf_impl(knownMaps)
1048
+
1049
+ def _resolve_plf_impl(self, knownMaps: dict[Path, MapFile]) -> MapFile:
1050
+ if len(knownMaps) == 0:
1051
+ return self.clone()
1052
+
1053
+ resolvedMap = MapFile()
1054
+ for seg in self._segmentsList:
1055
+ newSeg = seg.cloneNoSectionlist()
1056
+
1057
+ for sect in seg._sectionsList:
1058
+ if (otherMap := knownMaps.get(sect.filepath)) is not None:
1059
+ # Each segment of a plf is just a normal elf section
1060
+ partialSegment = None
1061
+ for x in otherMap._segmentsList:
1062
+ if x.name == sect.sectionType:
1063
+ partialSegment = x
1064
+ break
1065
+
1066
+ if partialSegment is not None:
1067
+ # Take all the sections from the plf map and insert them
1068
+ # into the new generated map, replacing the old sections
1069
+ # and symbols.
1070
+ for partialSect in partialSegment._sectionsList:
1071
+ sectTemp = partialSect.clone()
1072
+
1073
+ # Adjust the vram and vrom addresses of the section
1074
+ # because they are relative to zero.
1075
+ sectTemp.vram += sect.vram
1076
+ if sectTemp.vrom is not None and sect.vrom is not None and partialSegment.vrom is not None:
1077
+ sectTemp.vrom = sectTemp.vrom + sect.vrom - partialSegment.vrom
1078
+
1079
+ # Adjust vram and vrom of symbols too.
1080
+ for partialSym in sectTemp._symbols:
1081
+ partialSym.vram += sect.vram
1082
+ if partialSym.vrom is not None and sect.vrom is not None and partialSegment.vrom is not None:
1083
+ partialSym.vrom = partialSym.vrom + sect.vrom - partialSegment.vrom
1084
+
1085
+ newSeg._sectionsList.append(sectTemp)
1086
+ else:
1087
+ # Keep the original section if there are no sections
1088
+ # matching the section type in the plf.
1089
+ newSeg._sectionsList.append(sect.clone())
1090
+ else:
1091
+ # Keep the original section if there are no maps for this path
1092
+ newSeg._sectionsList.append(sect.clone())
1093
+ pass
1094
+
1095
+ resolvedMap._segmentsList.append(newSeg)
1096
+ return resolvedMap
1097
+
1018
1098
 
1019
1099
  def printAsCsv(self, printVram: bool=True, skipWithoutSymbols: bool=True):
1020
1100
  print(self.toCsv(printVram=printVram, skipWithoutSymbols=skipWithoutSymbols), end="")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapfile_parser
3
- Version: 2.9.4
3
+ Version: 2.10.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.9.4,<3.0.0
54
+ mapfile_parser>=2.10.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.9.4"
93
+ mapfile_parser = "2.10.0"
98
94
  ```
99
95
 
100
96
  ## Versioning and changelog
@@ -0,0 +1,26 @@
1
+ mapfile_parser-2.10.0.dist-info/METADATA,sha256=bev5YplmuDHyinu7Z-YeBA2vOfcRkaAGlv84q64RGMs,5648
2
+ mapfile_parser-2.10.0.dist-info/WHEEL,sha256=qh5btqjVHmZ0HjWePGI70zAW_wMd0f-tWtnLMFx5EDA,105
3
+ mapfile_parser-2.10.0.dist-info/licenses/LICENSE,sha256=FT7oxTcFUtz2c5eYIYePfzj2UD3hvxtLTa3FWz_nJuM,1073
4
+ mapfile_parser.libs/libgcc_s-0366c7ba.so.1,sha256=QjFj5R7pVqB-p92h2JTCmlyfd3UKsVGW_Y_l3SqOAaU,2753157
5
+ mapfile_parser/__init__.py,sha256=_IAX_b96JCG31ewTcS4cBCQW2hKV878G6ThikxqUEks,856
6
+ mapfile_parser/__main__.py,sha256=vErQTK2miHF7NseqLgI567tbFUjOrQ7UNxXOr_FwBhc,2176
7
+ mapfile_parser/frontends/__init__.py,sha256=RIUBbM6crp4V4EeMQy0whTonYauh0Oi2oaxu1NfWNao,512
8
+ mapfile_parser/frontends/bss_check.py,sha256=RierwrcKodWAf_-lD4xm9CjF_gh7ponlx0qEacRXKBk,9666
9
+ mapfile_parser/frontends/first_diff.py,sha256=DyQRGHlYTVgfqEo6S25l335DgfJa2XbJ_V37-RQPmjM,10037
10
+ mapfile_parser/frontends/jsonify.py,sha256=xchQspD7p0ai4ZzcKNgLN8pF9K56BGZN0YfcSUwWS5A,3550
11
+ mapfile_parser/frontends/objdiff_report.py,sha256=2PnRn8dNBfAYNyixxT88PvQVcRggWB-YeDD9KDR-rSE,19767
12
+ mapfile_parser/frontends/pj64_syms.py,sha256=uQKjBM7qSAfeD9GvURpb_k-TdzynY3XINjp5jli_oJw,3213
13
+ mapfile_parser/frontends/progress.py,sha256=QAzuds8q9gZVin7fgfeB_1bjKwnNYTfd31P_6rOHnRA,5601
14
+ mapfile_parser/frontends/sym_info.py,sha256=10AA3CCIEvyjhnp9nOldaPeh2AdQpwh5vH79-1yVknc,4448
15
+ mapfile_parser/frontends/symbol_sizes_csv.py,sha256=Jr9hBYsMpq7sbLgMLiNi8u_qNXlAy1pOyTZKVvnI_hA,4050
16
+ mapfile_parser/frontends/upload_frogress.py,sha256=PD9XupSd5LeD-xMjVUOjWDcQqK3gt4-1ykf7VVGBMoU,6528
17
+ mapfile_parser/internals/__init__.py,sha256=WW--q8KRIfYTQLOMvRO7PCMSf7uWk-I1T20KU0C2a_0,327
18
+ mapfile_parser/internals/objdiff_report.py,sha256=sZh7rUHdoWJfZKQ3EIeuNH9LqdEis2t7heCo1OOwKJU,6214
19
+ mapfile_parser/mapfile.py,sha256=FSWKugZL_F2stvJ8o1MdgvaBeEJhJRRpm62JQ2TG_JA,42916
20
+ mapfile_parser/mapfile_parser.cpython-39-arm-linux-gnueabihf.so,sha256=wmpBNKCWuT4GOWFHqvO5b_4v7BK_pWO-SPIYUFZ6Cm0,3152869
21
+ mapfile_parser/mapfile_parser.pyi,sha256=AuaCWiMySw-oBr-AR2NSbYbhpVP8TGS16rMeey6wc28,11227
22
+ mapfile_parser/mapfile_rs.py,sha256=0sVtLGvz5SMH5bKeTYu-3sM0f-_xXFRfDyY2g1GDh54,4078
23
+ mapfile_parser/progress_stats.py,sha256=T9V52QIoNBtvsPAbYRlCOAio95Z8VxzZep8bCc1J-H0,2535
24
+ mapfile_parser/progress_stats_rs.py,sha256=Rc9-PuZoKWVTO9TEIRk3Mpw0v6FdCFaJk2h7jUGyT_0,483
25
+ mapfile_parser/utils.py,sha256=Bz6pcuR9lax72Y7avgbOIBlyN-1GcxfDxz5iBodr3n0,1517
26
+ mapfile_parser-2.10.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: maturin (1.8.6)
2
+ Generator: maturin (1.9.4)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp39-cp39-musllinux_1_2_armv7l
@@ -1,26 +0,0 @@
1
- mapfile_parser-2.9.4.dist-info/METADATA,sha256=caVcmO4gT_gP9yjCNcy8wWsLvAq20B3gtz95fQ3VfKU,5810
2
- mapfile_parser-2.9.4.dist-info/WHEEL,sha256=3pmQ0_GUz8dFwucgTjtVJ_sBRdaTjahuPVfbh3xRtdg,105
3
- mapfile_parser-2.9.4.dist-info/licenses/LICENSE,sha256=FT7oxTcFUtz2c5eYIYePfzj2UD3hvxtLTa3FWz_nJuM,1073
4
- mapfile_parser.libs/libgcc_s-5b5488a6.so.1,sha256=HGKUsVmTeNAxEdSy7Ua5Vh_I9FN3RCbPWzvZ7H_TrwE,2749061
5
- mapfile_parser/__init__.py,sha256=LXglMB86pxkPrX_nAqAY2Ma_QV4xfGwmEpV9-a6LTy4,855
6
- mapfile_parser/__main__.py,sha256=vErQTK2miHF7NseqLgI567tbFUjOrQ7UNxXOr_FwBhc,2176
7
- mapfile_parser/frontends/__init__.py,sha256=RIUBbM6crp4V4EeMQy0whTonYauh0Oi2oaxu1NfWNao,512
8
- mapfile_parser/frontends/bss_check.py,sha256=O50pVG8uCp7poEqtrCbh05eIC_TYq3OIaD5VCZz4xGQ,8328
9
- mapfile_parser/frontends/first_diff.py,sha256=P5CqdGM_X7-WCcW7ubktKI6fnhHxezc1R0aL4_v3bOA,8899
10
- mapfile_parser/frontends/jsonify.py,sha256=Xq4fha2wJ70WH0an4BXaLnwgjYhNgAwTvrZZZoicRNQ,2654
11
- mapfile_parser/frontends/objdiff_report.py,sha256=d3I9PgjFIbWIoz_ZDAz58CMOMDrHNEiXwLOAVIlTzUo,18902
12
- mapfile_parser/frontends/pj64_syms.py,sha256=mJwiVGKGBoNrI-6VB4UJSVz7mIlihivX3KvUGRtoyMY,2332
13
- mapfile_parser/frontends/progress.py,sha256=j-6OtUCx8af8f3mcy1njA8AEEkR3mYf9_caCh-gFWDY,4563
14
- mapfile_parser/frontends/sym_info.py,sha256=CGpMdOHUpZslvTe8RpGJ-xrYhEjkhuzYKSJS4FZ60WI,3536
15
- mapfile_parser/frontends/symbol_sizes_csv.py,sha256=HMOBwAu_pN5dufiT-SEGg7cnIAVkyIDmVelP3YIyq0c,3138
16
- mapfile_parser/frontends/upload_frogress.py,sha256=ei3pSz2rzVpDj-0CASnPuyqqhu5Lm90mZ_2tsbF9ALU,5639
17
- mapfile_parser/internals/__init__.py,sha256=WW--q8KRIfYTQLOMvRO7PCMSf7uWk-I1T20KU0C2a_0,327
18
- mapfile_parser/internals/objdiff_report.py,sha256=sZh7rUHdoWJfZKQ3EIeuNH9LqdEis2t7heCo1OOwKJU,6214
19
- mapfile_parser/mapfile.py,sha256=498NSrZtorSe-W0BzxnMtq-d0xOBBcaj8fB9iRK4Tmg,38834
20
- mapfile_parser/mapfile_parser.cpython-39-arm-linux-gnueabihf.so,sha256=13efsrFLy0QUnKzOgQ-vkC9ND9noaJeZLoEjvOs7M0k,3185637
21
- mapfile_parser/mapfile_parser.pyi,sha256=AuaCWiMySw-oBr-AR2NSbYbhpVP8TGS16rMeey6wc28,11227
22
- mapfile_parser/mapfile_rs.py,sha256=0sVtLGvz5SMH5bKeTYu-3sM0f-_xXFRfDyY2g1GDh54,4078
23
- mapfile_parser/progress_stats.py,sha256=T9V52QIoNBtvsPAbYRlCOAio95Z8VxzZep8bCc1J-H0,2535
24
- mapfile_parser/progress_stats_rs.py,sha256=Rc9-PuZoKWVTO9TEIRk3Mpw0v6FdCFaJk2h7jUGyT_0,483
25
- mapfile_parser/utils.py,sha256=Bz6pcuR9lax72Y7avgbOIBlyN-1GcxfDxz5iBodr3n0,1517
26
- mapfile_parser-2.9.4.dist-info/RECORD,,
Binary file