24
24
from os import sep
25
25
from os .path import (basename , dirname , join , relpath , abspath , commonprefix ,
26
26
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
-
32
27
import re
33
28
import csv
34
29
import json
39
34
from jinja2 import FileSystemLoader , StrictUndefined
40
35
from jinja2 .environment import Environment
41
36
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
44
47
45
48
46
49
class _Parser (object ):
@@ -105,33 +108,36 @@ def parse_mapfile(self, mapfile):
105
108
106
109
class _GccParser (_Parser ):
107
110
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
+ )
109
114
RE_STD_SECTION = re .compile (r'^\s+.*0x(\w{8,16})\s+0x(\w+)\s(.+)$' )
110
115
RE_FILL_SECTION = re .compile (r'^\s*\*fill\*\s+0x(\w{8,16})\s+0x(\w+).*$' )
111
116
OBJECT_EXTENSIONS = (".o" , ".obj" )
112
117
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
+ )
115
124
116
125
def check_new_section (self , line ):
117
126
""" Check whether a new section in a map file has been detected
118
127
119
128
Positional arguments:
120
129
line - the line to check for a new section
121
130
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
123
132
otherwise
124
133
"""
125
134
for i in self .ALL_SECTIONS :
126
135
if line .startswith (i ):
127
- # should name of the section (assuming it's a known one)
128
136
return i
129
-
130
137
if line .startswith ('.' ):
131
- return 'unknown' # all others are classified are unknown
138
+ return 'unknown'
132
139
else :
133
- return False # everything else, means no change in section
134
-
140
+ return None
135
141
136
142
def parse_object_name (self , line ):
137
143
""" Parse a path to object file
@@ -158,8 +164,10 @@ def parse_object_name(self, line):
158
164
return join ('[lib]' , test_re_obj_name .group (2 ),
159
165
test_re_obj_name .group (3 ))
160
166
else :
161
- if (not line .startswith ("LONG" ) and
162
- not line .startswith ("linker stubs" )):
167
+ if (
168
+ not line .startswith ("LONG" ) and
169
+ not line .startswith ("linker stubs" )
170
+ ):
163
171
print ("Unknown object name found in GCC map file: %s"
164
172
% line )
165
173
return '[misc]'
@@ -168,8 +176,8 @@ def parse_section(self, line):
168
176
""" Parse data from a section of gcc map file
169
177
170
178
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
179
+ 0x00004308 0x7c ./BUILD/K64F/GCC_ARM/spi_api.o
180
+ .text 0x00000608 0x198 ./BUILD/K64F/HAL_CM4.o
173
181
174
182
Positional arguments:
175
183
line - the line to parse a section from
@@ -215,7 +223,11 @@ def parse_mapfile(self, file_desc):
215
223
self .module_add (object_name , object_size , current_section )
216
224
217
225
common_prefix = dirname (commonprefix ([
218
- o for o in self .modules .keys () if (o .endswith (self .OBJECT_EXTENSIONS ) and not o .startswith ("[lib]" ))]))
226
+ o for o in self .modules .keys ()
227
+ if (
228
+ o .endswith (self .OBJECT_EXTENSIONS )
229
+ and not o .startswith ("[lib]" )
230
+ )]))
219
231
new_modules = {}
220
232
for name , stats in self .modules .items ():
221
233
if name .startswith ("[lib]" ):
@@ -245,9 +257,13 @@ def parse_object_name(self, line):
245
257
else :
246
258
is_obj = re .match (self .RE_OBJECT , line )
247
259
if is_obj :
248
- return join ('[lib]' , basename (is_obj .group (1 )), is_obj .group (3 ))
260
+ return join (
261
+ '[lib]' , basename (is_obj .group (1 )), is_obj .group (3 )
262
+ )
249
263
else :
250
- print ("Malformed input found when parsing ARMCC map: %s" % line )
264
+ print (
265
+ "Malformed input found when parsing ARMCC map: %s" % line
266
+ )
251
267
return '[misc]'
252
268
253
269
def parse_section (self , line ):
@@ -260,7 +276,7 @@ def parse_section(self, line):
260
276
261
277
Positional arguments:
262
278
line - the line to parse the section data from
263
- """
279
+ """ # noqa: E501
264
280
test_re = re .match (self .RE , line )
265
281
266
282
if test_re :
@@ -276,8 +292,10 @@ def parse_section(self, line):
276
292
elif test_re .group (3 ) == 'Code' :
277
293
section = '.text'
278
294
else :
279
- print ("Malformed input found when parsing armcc map: %s, %r"
280
- % (line , test_re .groups ()))
295
+ print (
296
+ "Malformed input found when parsing armcc map: %s, %r"
297
+ % (line , test_re .groups ())
298
+ )
281
299
282
300
return ["" , 0 , "" ]
283
301
@@ -307,10 +325,20 @@ def parse_mapfile(self, file_desc):
307
325
self .module_add (* self .parse_section (line ))
308
326
309
327
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]" ))]))
328
+ o for o in self .modules .keys ()
329
+ if (
330
+ o .endswith (self .OBJECT_EXTENSIONS )
331
+ and o != "anon$$obj.o"
332
+ and o != "anon$$obj.obj"
333
+ and not o .startswith ("[lib]" )
334
+ )]))
311
335
new_modules = {}
312
336
for name , stats in self .modules .items ():
313
- if name == "anon$$obj.o" or name == "anon$$obj.obj" or name .startswith ("[lib]" ):
337
+ if (
338
+ name == "anon$$obj.o"
339
+ or name == "anon$$obj.obj"
340
+ or name .startswith ("[lib]" )
341
+ ):
314
342
new_modules [name ] = stats
315
343
elif name .endswith (self .OBJECT_EXTENSIONS ):
316
344
new_modules [relpath (name , common_prefix )] = stats
@@ -365,11 +393,13 @@ def parse_section(self, line):
365
393
366
394
Positional_arguments:
367
395
line - the line to parse section data from
368
- """
396
+ """ # noqa: E501
369
397
test_re = re .match (self .RE , line )
370
398
if test_re :
371
- if (test_re .group (2 ) == 'const' or
372
- test_re .group (2 ) == 'ro code' ):
399
+ if (
400
+ test_re .group (2 ) == 'const' or
401
+ test_re .group (2 ) == 'ro code'
402
+ ):
373
403
section = '.text'
374
404
elif (test_re .group (2 ) == 'zero' or
375
405
test_re .group (2 ) == 'uninit' ):
@@ -378,7 +408,7 @@ def parse_section(self, line):
378
408
elif test_re .group (1 )[0 :6 ] == 'CSTACK' :
379
409
section = '.stack'
380
410
else :
381
- section = '.bss' # default section
411
+ section = '.bss' # default section
382
412
383
413
elif test_re .group (2 ) == 'inited' :
384
414
section = '.data'
@@ -409,7 +439,8 @@ def check_new_library(self, line):
409
439
410
440
def check_new_object_lib (self , line ):
411
441
"""
412
- Searches for objects within a library section and returns name. Example:
442
+ Searches for objects within a library section and returns name.
443
+ Example:
413
444
rt7M_tl.a: [44]
414
445
ABImemclr4.o 6
415
446
ABImemcpy_unaligned.o 118
@@ -435,7 +466,10 @@ def parse_command_line(self, lines):
435
466
break
436
467
for arg in line .split (" " ):
437
468
arg = arg .rstrip (" \n " )
438
- if (not arg .startswith ("-" )) and arg .endswith (self .OBJECT_EXTENSIONS ):
469
+ if (
470
+ not arg .startswith ("-" )
471
+ and arg .endswith (self .OBJECT_EXTENSIONS )
472
+ ):
439
473
self .cmd_modules [basename (arg )] = arg
440
474
441
475
common_prefix = dirname (commonprefix (list (self .cmd_modules .values ())))
@@ -458,7 +492,7 @@ def parse_mapfile(self, file_desc):
458
492
for line in infile :
459
493
self .module_add (* self .parse_section (line ))
460
494
461
- if line .startswith ('*** MODULE SUMMARY' ): # finish section
495
+ if line .startswith ('*** MODULE SUMMARY' ): # finish section
462
496
break
463
497
464
498
current_library = ""
@@ -484,7 +518,6 @@ class MemapParser(object):
484
518
print_sections = ('.text' , '.data' , '.bss' )
485
519
delta_sections = ('.text-delta' , '.data-delta' , '.bss-delta' )
486
520
487
-
488
521
# sections to print info (generic for all toolchains)
489
522
sections = _Parser .SECTIONS
490
523
misc_flash_sections = _Parser .MISC_FLASH_SECTIONS
@@ -498,7 +531,6 @@ def __init__(self):
498
531
# short version with specific depth
499
532
self .short_modules = dict ()
500
533
501
-
502
534
# Memory report (sections + summary)
503
535
self .mem_report = []
504
536
@@ -528,7 +560,7 @@ def reduce_depth(self, depth):
528
560
mbed-os/drivers
529
561
530
562
"""
531
- if depth == 0 or depth == None :
563
+ if depth == 0 or depth is None :
532
564
self .short_modules = deepcopy (self .modules )
533
565
else :
534
566
self .short_modules = dict ()
@@ -539,8 +571,9 @@ def reduce_depth(self, depth):
539
571
new_name = join (* split_name [:depth ])
540
572
self .short_modules .setdefault (new_name , defaultdict (int ))
541
573
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 ]
574
+ self .short_modules [new_name ][section_idx ] += value
575
+ delta_name = section_idx + '-delta'
576
+ self .short_modules [new_name ][delta_name ] += value
544
577
if self .old_modules :
545
578
for module_name , v in self .old_modules .items ():
546
579
split_name = module_name .split (sep )
@@ -549,7 +582,8 @@ def reduce_depth(self, depth):
549
582
new_name = join (* split_name [:depth ])
550
583
self .short_modules .setdefault (new_name , defaultdict (int ))
551
584
for section_idx , value in v .items ():
552
- self .short_modules [new_name ][section_idx + '-delta' ] -= self .old_modules [module_name ][section_idx ]
585
+ delta_name = section_idx + '-delta'
586
+ self .short_modules [new_name ][delta_name ] -= value
553
587
554
588
export_formats = ["json" , "csv-ci" , "html" , "table" ]
555
589
@@ -657,7 +691,10 @@ def generate_html(self, file_desc):
657
691
if not modules :
658
692
break
659
693
next_module = modules .pop (0 )
660
- if not any (cld ['name' ] == next_module for cld in cur_text ['children' ]):
694
+ if not any (
695
+ cld ['name' ] == next_module
696
+ for cld in cur_text ['children' ]
697
+ ):
661
698
break
662
699
cur_text = self ._move_up_tree (cur_text , next_module )
663
700
cur_data = self ._move_up_tree (cur_data , next_module )
@@ -759,8 +796,10 @@ def generate_table(self, file_desc):
759
796
row = [i ]
760
797
761
798
for k in self .print_sections :
762
- row .append ("{}({:+})" .format (self .short_modules [i ][k ],
763
- self .short_modules [i ][k + "-delta" ]))
799
+ row .append ("{}({:+})" .format (
800
+ self .short_modules [i ][k ],
801
+ self .short_modules [i ][k + "-delta" ]
802
+ ))
764
803
765
804
table .add_row (row )
766
805
@@ -815,7 +854,7 @@ def compute_report(self):
815
854
for name , sizes in sorted (self .short_modules .items ()):
816
855
self .mem_report .append ({
817
856
"module" : name ,
818
- "size" :{
857
+ "size" : {
819
858
k : sizes .get (k , 0 ) for k in (self .print_sections +
820
859
self .delta_sections )
821
860
}
@@ -855,6 +894,7 @@ def parse(self, mapfile, toolchain):
855
894
print ("I/O error({0}): {1}" .format (error .errno , error .strerror ))
856
895
return False
857
896
897
+
858
898
def main ():
859
899
"""Entry Point"""
860
900
version = '0.4.0'
@@ -912,16 +952,20 @@ def main():
912
952
913
953
returned_string = None
914
954
# 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
955
+ if args .output is not None :
956
+ returned_string = memap .generate_output (
957
+ args .export ,
958
+ depth ,
959
+ args .output
960
+ )
961
+ else : # Write output in screen
919
962
returned_string = memap .generate_output (args .export , depth )
920
963
921
964
if args .export == 'table' and returned_string :
922
965
print (returned_string )
923
966
924
967
exit (0 )
925
968
969
+
926
970
if __name__ == "__main__" :
927
971
main ()
0 commit comments