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,37 @@ 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
"""
134
+ line_s = line .strip ()
125
135
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 ):
128
137
return i
129
-
130
138
if line .startswith ('.' ):
131
- return 'unknown' # all others are classified are unknown
139
+ return 'unknown'
132
140
else :
133
- return False # everything else, means no change in section
134
-
141
+ return None
135
142
136
143
def parse_object_name (self , line ):
137
144
""" Parse a path to object file
@@ -158,8 +165,10 @@ def parse_object_name(self, line):
158
165
return join ('[lib]' , test_re_obj_name .group (2 ),
159
166
test_re_obj_name .group (3 ))
160
167
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
+ ):
163
172
print ("Unknown object name found in GCC map file: %s"
164
173
% line )
165
174
return '[misc]'
@@ -168,8 +177,8 @@ def parse_section(self, line):
168
177
""" Parse data from a section of gcc map file
169
178
170
179
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
173
182
174
183
Positional arguments:
175
184
line - the line to parse a section from
@@ -215,7 +224,11 @@ def parse_mapfile(self, file_desc):
215
224
self .module_add (object_name , object_size , current_section )
216
225
217
226
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
+ )]))
219
232
new_modules = {}
220
233
for name , stats in self .modules .items ():
221
234
if name .startswith ("[lib]" ):
@@ -245,9 +258,13 @@ def parse_object_name(self, line):
245
258
else :
246
259
is_obj = re .match (self .RE_OBJECT , line )
247
260
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
+ )
249
264
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
+ )
251
268
return '[misc]'
252
269
253
270
def parse_section (self , line ):
@@ -260,7 +277,7 @@ def parse_section(self, line):
260
277
261
278
Positional arguments:
262
279
line - the line to parse the section data from
263
- """
280
+ """ # noqa: E501
264
281
test_re = re .match (self .RE , line )
265
282
266
283
if test_re :
@@ -276,8 +293,10 @@ def parse_section(self, line):
276
293
elif test_re .group (3 ) == 'Code' :
277
294
section = '.text'
278
295
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
+ )
281
300
282
301
return ["" , 0 , "" ]
283
302
@@ -307,10 +326,20 @@ def parse_mapfile(self, file_desc):
307
326
self .module_add (* self .parse_section (line ))
308
327
309
328
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
+ )]))
311
336
new_modules = {}
312
337
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
+ ):
314
343
new_modules [name ] = stats
315
344
elif name .endswith (self .OBJECT_EXTENSIONS ):
316
345
new_modules [relpath (name , common_prefix )] = stats
@@ -365,11 +394,13 @@ def parse_section(self, line):
365
394
366
395
Positional_arguments:
367
396
line - the line to parse section data from
368
- """
397
+ """ # noqa: E501
369
398
test_re = re .match (self .RE , line )
370
399
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
+ ):
373
404
section = '.text'
374
405
elif (test_re .group (2 ) == 'zero' or
375
406
test_re .group (2 ) == 'uninit' ):
@@ -378,7 +409,7 @@ def parse_section(self, line):
378
409
elif test_re .group (1 )[0 :6 ] == 'CSTACK' :
379
410
section = '.stack'
380
411
else :
381
- section = '.bss' # default section
412
+ section = '.bss' # default section
382
413
383
414
elif test_re .group (2 ) == 'inited' :
384
415
section = '.data'
@@ -409,7 +440,8 @@ def check_new_library(self, line):
409
440
410
441
def check_new_object_lib (self , line ):
411
442
"""
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:
413
445
rt7M_tl.a: [44]
414
446
ABImemclr4.o 6
415
447
ABImemcpy_unaligned.o 118
@@ -435,7 +467,10 @@ def parse_command_line(self, lines):
435
467
break
436
468
for arg in line .split (" " ):
437
469
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
+ ):
439
474
self .cmd_modules [basename (arg )] = arg
440
475
441
476
common_prefix = dirname (commonprefix (list (self .cmd_modules .values ())))
@@ -458,7 +493,7 @@ def parse_mapfile(self, file_desc):
458
493
for line in infile :
459
494
self .module_add (* self .parse_section (line ))
460
495
461
- if line .startswith ('*** MODULE SUMMARY' ): # finish section
496
+ if line .startswith ('*** MODULE SUMMARY' ): # finish section
462
497
break
463
498
464
499
current_library = ""
@@ -484,7 +519,6 @@ class MemapParser(object):
484
519
print_sections = ('.text' , '.data' , '.bss' )
485
520
delta_sections = ('.text-delta' , '.data-delta' , '.bss-delta' )
486
521
487
-
488
522
# sections to print info (generic for all toolchains)
489
523
sections = _Parser .SECTIONS
490
524
misc_flash_sections = _Parser .MISC_FLASH_SECTIONS
@@ -498,7 +532,6 @@ def __init__(self):
498
532
# short version with specific depth
499
533
self .short_modules = dict ()
500
534
501
-
502
535
# Memory report (sections + summary)
503
536
self .mem_report = []
504
537
@@ -528,7 +561,7 @@ def reduce_depth(self, depth):
528
561
mbed-os/drivers
529
562
530
563
"""
531
- if depth == 0 or depth == None :
564
+ if depth == 0 or depth is None :
532
565
self .short_modules = deepcopy (self .modules )
533
566
else :
534
567
self .short_modules = dict ()
@@ -539,8 +572,9 @@ def reduce_depth(self, depth):
539
572
new_name = join (* split_name [:depth ])
540
573
self .short_modules .setdefault (new_name , defaultdict (int ))
541
574
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
544
578
if self .old_modules :
545
579
for module_name , v in self .old_modules .items ():
546
580
split_name = module_name .split (sep )
@@ -549,7 +583,8 @@ def reduce_depth(self, depth):
549
583
new_name = join (* split_name [:depth ])
550
584
self .short_modules .setdefault (new_name , defaultdict (int ))
551
585
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
553
588
554
589
export_formats = ["json" , "csv-ci" , "html" , "table" ]
555
590
@@ -657,7 +692,10 @@ def generate_html(self, file_desc):
657
692
if not modules :
658
693
break
659
694
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
+ ):
661
699
break
662
700
cur_text = self ._move_up_tree (cur_text , next_module )
663
701
cur_data = self ._move_up_tree (cur_data , next_module )
@@ -759,8 +797,10 @@ def generate_table(self, file_desc):
759
797
row = [i ]
760
798
761
799
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
+ ))
764
804
765
805
table .add_row (row )
766
806
@@ -815,7 +855,7 @@ def compute_report(self):
815
855
for name , sizes in sorted (self .short_modules .items ()):
816
856
self .mem_report .append ({
817
857
"module" : name ,
818
- "size" :{
858
+ "size" : {
819
859
k : sizes .get (k , 0 ) for k in (self .print_sections +
820
860
self .delta_sections )
821
861
}
@@ -855,6 +895,7 @@ def parse(self, mapfile, toolchain):
855
895
print ("I/O error({0}): {1}" .format (error .errno , error .strerror ))
856
896
return False
857
897
898
+
858
899
def main ():
859
900
"""Entry Point"""
860
901
version = '0.4.0'
@@ -912,16 +953,20 @@ def main():
912
953
913
954
returned_string = None
914
955
# 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
919
963
returned_string = memap .generate_output (args .export , depth )
920
964
921
965
if args .export == 'table' and returned_string :
922
966
print (returned_string )
923
967
924
968
exit (0 )
925
969
970
+
926
971
if __name__ == "__main__" :
927
972
main ()
0 commit comments