Skip to content

Commit 8e02592

Browse files
author
Cruz Monrreal
authored
Merge pull request #10348 from theotherjimmy/fix-memap-m33
Parse M33 + GCC_ARM map files
2 parents b419cfc + 002a2b1 commit 8e02592

File tree

1 file changed

+95
-50
lines changed

1 file changed

+95
-50
lines changed

tools/memap.py

Lines changed: 95 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@
2424
from os import sep
2525
from os.path import (basename, dirname, join, relpath, abspath, commonprefix,
2626
splitext)
27-
28-
# Be sure that the tools directory is in the search path
29-
ROOT = abspath(join(dirname(__file__), ".."))
30-
path.insert(0, ROOT)
31-
3227
import re
3328
import csv
3429
import json
@@ -39,8 +34,16 @@
3934
from jinja2 import FileSystemLoader, StrictUndefined
4035
from jinja2.environment import Environment
4136

42-
from tools.utils import (argparse_filestring_type, argparse_lowercase_hyphen_type,
43-
argparse_uppercase_type)
37+
38+
# Be sure that the tools directory is in the search path
39+
ROOT = abspath(join(dirname(__file__), ".."))
40+
path.insert(0, ROOT)
41+
42+
from tools.utils import (
43+
argparse_filestring_type,
44+
argparse_lowercase_hyphen_type,
45+
argparse_uppercase_type
46+
) # noqa: E402
4447

4548

4649
class _Parser(object):
@@ -105,33 +108,37 @@ def parse_mapfile(self, mapfile):
105108

106109
class _GccParser(_Parser):
107110
RE_OBJECT_FILE = re.compile(r'^(.+\/.+\.o(bj)?)$')
108-
RE_LIBRARY_OBJECT = re.compile(r'^.+' + r''.format(sep) + r'lib((.+\.a)\((.+\.o(bj)?)\))$')
111+
RE_LIBRARY_OBJECT = re.compile(
112+
r'^.+' + r''.format(sep) + r'lib((.+\.a)\((.+\.o(bj)?)\))$'
113+
)
109114
RE_STD_SECTION = re.compile(r'^\s+.*0x(\w{8,16})\s+0x(\w+)\s(.+)$')
110115
RE_FILL_SECTION = re.compile(r'^\s*\*fill\*\s+0x(\w{8,16})\s+0x(\w+).*$')
111116
OBJECT_EXTENSIONS = (".o", ".obj")
112117

113-
ALL_SECTIONS = _Parser.SECTIONS + _Parser.OTHER_SECTIONS + \
114-
_Parser.MISC_FLASH_SECTIONS + ('unknown', 'OUTPUT')
118+
ALL_SECTIONS = (
119+
_Parser.SECTIONS
120+
+ _Parser.OTHER_SECTIONS
121+
+ _Parser.MISC_FLASH_SECTIONS
122+
+ ('unknown', 'OUTPUT')
123+
)
115124

116125
def check_new_section(self, line):
117126
""" Check whether a new section in a map file has been detected
118127
119128
Positional arguments:
120129
line - the line to check for a new section
121130
122-
return value - A section name, if a new section was found, False
131+
return value - A section name, if a new section was found, None
123132
otherwise
124133
"""
134+
line_s = line.strip()
125135
for i in self.ALL_SECTIONS:
126-
if line.startswith(i):
127-
# should name of the section (assuming it's a known one)
136+
if line_s.startswith(i):
128137
return i
129-
130138
if line.startswith('.'):
131-
return 'unknown' # all others are classified are unknown
139+
return 'unknown'
132140
else:
133-
return False # everything else, means no change in section
134-
141+
return None
135142

136143
def parse_object_name(self, line):
137144
""" Parse a path to object file
@@ -158,8 +165,10 @@ def parse_object_name(self, line):
158165
return join('[lib]', test_re_obj_name.group(2),
159166
test_re_obj_name.group(3))
160167
else:
161-
if (not line.startswith("LONG") and
162-
not line.startswith("linker stubs")):
168+
if (
169+
not line.startswith("LONG") and
170+
not line.startswith("linker stubs")
171+
):
163172
print("Unknown object name found in GCC map file: %s"
164173
% line)
165174
return '[misc]'
@@ -168,8 +177,8 @@ def parse_section(self, line):
168177
""" Parse data from a section of gcc map file
169178
170179
examples:
171-
0x00004308 0x7c ./BUILD/K64F/GCC_ARM/mbed-os/hal/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/spi_api.o
172-
.text 0x00000608 0x198 ./BUILD/K64F/GCC_ARM/mbed-os/core/mbed-rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN/HAL_CM4.o
180+
0x00004308 0x7c ./BUILD/K64F/GCC_ARM/spi_api.o
181+
.text 0x00000608 0x198 ./BUILD/K64F/HAL_CM4.o
173182
174183
Positional arguments:
175184
line - the line to parse a section from
@@ -215,7 +224,11 @@ def parse_mapfile(self, file_desc):
215224
self.module_add(object_name, object_size, current_section)
216225

217226
common_prefix = dirname(commonprefix([
218-
o for o in self.modules.keys() if (o.endswith(self.OBJECT_EXTENSIONS) and not o.startswith("[lib]"))]))
227+
o for o in self.modules.keys()
228+
if (
229+
o.endswith(self.OBJECT_EXTENSIONS)
230+
and not o.startswith("[lib]")
231+
)]))
219232
new_modules = {}
220233
for name, stats in self.modules.items():
221234
if name.startswith("[lib]"):
@@ -245,9 +258,13 @@ def parse_object_name(self, line):
245258
else:
246259
is_obj = re.match(self.RE_OBJECT, line)
247260
if is_obj:
248-
return join('[lib]', basename(is_obj.group(1)), is_obj.group(3))
261+
return join(
262+
'[lib]', basename(is_obj.group(1)), is_obj.group(3)
263+
)
249264
else:
250-
print("Malformed input found when parsing ARMCC map: %s" % line)
265+
print(
266+
"Malformed input found when parsing ARMCC map: %s" % line
267+
)
251268
return '[misc]'
252269

253270
def parse_section(self, line):
@@ -260,7 +277,7 @@ def parse_section(self, line):
260277
261278
Positional arguments:
262279
line - the line to parse the section data from
263-
"""
280+
""" # noqa: E501
264281
test_re = re.match(self.RE, line)
265282

266283
if test_re:
@@ -276,8 +293,10 @@ def parse_section(self, line):
276293
elif test_re.group(3) == 'Code':
277294
section = '.text'
278295
else:
279-
print("Malformed input found when parsing armcc map: %s, %r"
280-
% (line, test_re.groups()))
296+
print(
297+
"Malformed input found when parsing armcc map: %s, %r"
298+
% (line, test_re.groups())
299+
)
281300

282301
return ["", 0, ""]
283302

@@ -307,10 +326,20 @@ def parse_mapfile(self, file_desc):
307326
self.module_add(*self.parse_section(line))
308327

309328
common_prefix = dirname(commonprefix([
310-
o for o in self.modules.keys() if (o.endswith(self.OBJECT_EXTENSIONS) and o != "anon$$obj.o" and o != "anon$$obj.obj" and not o.startswith("[lib]"))]))
329+
o for o in self.modules.keys()
330+
if (
331+
o.endswith(self.OBJECT_EXTENSIONS)
332+
and o != "anon$$obj.o"
333+
and o != "anon$$obj.obj"
334+
and not o.startswith("[lib]")
335+
)]))
311336
new_modules = {}
312337
for name, stats in self.modules.items():
313-
if name == "anon$$obj.o" or name == "anon$$obj.obj" or name.startswith("[lib]"):
338+
if (
339+
name == "anon$$obj.o"
340+
or name == "anon$$obj.obj"
341+
or name.startswith("[lib]")
342+
):
314343
new_modules[name] = stats
315344
elif name.endswith(self.OBJECT_EXTENSIONS):
316345
new_modules[relpath(name, common_prefix)] = stats
@@ -365,11 +394,13 @@ def parse_section(self, line):
365394
366395
Positional_arguments:
367396
line - the line to parse section data from
368-
"""
397+
""" # noqa: E501
369398
test_re = re.match(self.RE, line)
370399
if test_re:
371-
if (test_re.group(2) == 'const' or
372-
test_re.group(2) == 'ro code'):
400+
if (
401+
test_re.group(2) == 'const' or
402+
test_re.group(2) == 'ro code'
403+
):
373404
section = '.text'
374405
elif (test_re.group(2) == 'zero' or
375406
test_re.group(2) == 'uninit'):
@@ -378,7 +409,7 @@ def parse_section(self, line):
378409
elif test_re.group(1)[0:6] == 'CSTACK':
379410
section = '.stack'
380411
else:
381-
section = '.bss' # default section
412+
section = '.bss' # default section
382413

383414
elif test_re.group(2) == 'inited':
384415
section = '.data'
@@ -409,7 +440,8 @@ def check_new_library(self, line):
409440

410441
def check_new_object_lib(self, line):
411442
"""
412-
Searches for objects within a library section and returns name. Example:
443+
Searches for objects within a library section and returns name.
444+
Example:
413445
rt7M_tl.a: [44]
414446
ABImemclr4.o 6
415447
ABImemcpy_unaligned.o 118
@@ -435,7 +467,10 @@ def parse_command_line(self, lines):
435467
break
436468
for arg in line.split(" "):
437469
arg = arg.rstrip(" \n")
438-
if (not arg.startswith("-")) and arg.endswith(self.OBJECT_EXTENSIONS):
470+
if (
471+
not arg.startswith("-")
472+
and arg.endswith(self.OBJECT_EXTENSIONS)
473+
):
439474
self.cmd_modules[basename(arg)] = arg
440475

441476
common_prefix = dirname(commonprefix(list(self.cmd_modules.values())))
@@ -458,7 +493,7 @@ def parse_mapfile(self, file_desc):
458493
for line in infile:
459494
self.module_add(*self.parse_section(line))
460495

461-
if line.startswith('*** MODULE SUMMARY'): # finish section
496+
if line.startswith('*** MODULE SUMMARY'): # finish section
462497
break
463498

464499
current_library = ""
@@ -484,7 +519,6 @@ class MemapParser(object):
484519
print_sections = ('.text', '.data', '.bss')
485520
delta_sections = ('.text-delta', '.data-delta', '.bss-delta')
486521

487-
488522
# sections to print info (generic for all toolchains)
489523
sections = _Parser.SECTIONS
490524
misc_flash_sections = _Parser.MISC_FLASH_SECTIONS
@@ -498,7 +532,6 @@ def __init__(self):
498532
# short version with specific depth
499533
self.short_modules = dict()
500534

501-
502535
# Memory report (sections + summary)
503536
self.mem_report = []
504537

@@ -528,7 +561,7 @@ def reduce_depth(self, depth):
528561
mbed-os/drivers
529562
530563
"""
531-
if depth == 0 or depth == None:
564+
if depth == 0 or depth is None:
532565
self.short_modules = deepcopy(self.modules)
533566
else:
534567
self.short_modules = dict()
@@ -539,8 +572,9 @@ def reduce_depth(self, depth):
539572
new_name = join(*split_name[:depth])
540573
self.short_modules.setdefault(new_name, defaultdict(int))
541574
for section_idx, value in v.items():
542-
self.short_modules[new_name][section_idx] += self.modules[module_name][section_idx]
543-
self.short_modules[new_name][section_idx + '-delta'] += self.modules[module_name][section_idx]
575+
self.short_modules[new_name][section_idx] += value
576+
delta_name = section_idx + '-delta'
577+
self.short_modules[new_name][delta_name] += value
544578
if self.old_modules:
545579
for module_name, v in self.old_modules.items():
546580
split_name = module_name.split(sep)
@@ -549,7 +583,8 @@ def reduce_depth(self, depth):
549583
new_name = join(*split_name[:depth])
550584
self.short_modules.setdefault(new_name, defaultdict(int))
551585
for section_idx, value in v.items():
552-
self.short_modules[new_name][section_idx + '-delta'] -= self.old_modules[module_name][section_idx]
586+
delta_name = section_idx + '-delta'
587+
self.short_modules[new_name][delta_name] -= value
553588

554589
export_formats = ["json", "csv-ci", "html", "table"]
555590

@@ -657,7 +692,10 @@ def generate_html(self, file_desc):
657692
if not modules:
658693
break
659694
next_module = modules.pop(0)
660-
if not any(cld['name'] == next_module for cld in cur_text['children']):
695+
if not any(
696+
cld['name'] == next_module
697+
for cld in cur_text['children']
698+
):
661699
break
662700
cur_text = self._move_up_tree(cur_text, next_module)
663701
cur_data = self._move_up_tree(cur_data, next_module)
@@ -759,8 +797,10 @@ def generate_table(self, file_desc):
759797
row = [i]
760798

761799
for k in self.print_sections:
762-
row.append("{}({:+})".format(self.short_modules[i][k],
763-
self.short_modules[i][k + "-delta"]))
800+
row.append("{}({:+})".format(
801+
self.short_modules[i][k],
802+
self.short_modules[i][k + "-delta"]
803+
))
764804

765805
table.add_row(row)
766806

@@ -815,7 +855,7 @@ def compute_report(self):
815855
for name, sizes in sorted(self.short_modules.items()):
816856
self.mem_report.append({
817857
"module": name,
818-
"size":{
858+
"size": {
819859
k: sizes.get(k, 0) for k in (self.print_sections +
820860
self.delta_sections)
821861
}
@@ -855,6 +895,7 @@ def parse(self, mapfile, toolchain):
855895
print("I/O error({0}): {1}".format(error.errno, error.strerror))
856896
return False
857897

898+
858899
def main():
859900
"""Entry Point"""
860901
version = '0.4.0'
@@ -912,16 +953,20 @@ def main():
912953

913954
returned_string = None
914955
# Write output in file
915-
if args.output != None:
916-
returned_string = memap.generate_output(args.export, \
917-
depth, args.output)
918-
else: # Write output in screen
956+
if args.output is not None:
957+
returned_string = memap.generate_output(
958+
args.export,
959+
depth,
960+
args.output
961+
)
962+
else: # Write output in screen
919963
returned_string = memap.generate_output(args.export, depth)
920964

921965
if args.export == 'table' and returned_string:
922966
print(returned_string)
923967

924968
exit(0)
925969

970+
926971
if __name__ == "__main__":
927972
main()

0 commit comments

Comments
 (0)