20
20
RE_IAR = re .compile (
21
21
r'^\s+(.+)\s+(zero|const|ro code|inited|uninit)\s'
22
22
r'+0x(\w{8})\s+0x(\w+)\s+(.+)\s.+$' )
23
- RE_LIB_MATCH = re .compile ("^.*/(.*\.a)\((.*)\)$" )
24
23
25
24
class MemapParser (object ):
26
25
"""An object that represents parsed results, parses the memory map files,
@@ -38,16 +37,13 @@ class MemapParser(object):
38
37
39
38
# sections to print info (generic for all toolchains)
40
39
sections = ('.text' , '.data' , '.bss' , '.heap' , '.stack' )
41
- MAXDEPTH = object ()
42
40
43
- def __init__ (self , depth = 2 ):
41
+ def __init__ (self , detailed_misc = False ):
44
42
""" General initialization
45
43
"""
46
-
47
- self .depth = depth
48
-
49
- self .mapfile = None
50
-
44
+ #
45
+ self .detailed_misc = detailed_misc
46
+
51
47
# list of all modules and their sections
52
48
self .modules = dict ()
53
49
@@ -102,7 +98,7 @@ def check_new_section_gcc(self, line):
102
98
else :
103
99
return False # everything else, means no change in section
104
100
105
-
101
+
106
102
def path_object_to_module_name (self , txt ):
107
103
""" Parse a path to object file to extract it's module and object data
108
104
@@ -111,25 +107,32 @@ def path_object_to_module_name(self, txt):
111
107
"""
112
108
113
109
txt = txt .replace ('\\ ' , '/' )
114
- name = txt .split ('/' )
115
- mapfile_beginning = os .path .dirname (self .mapfile ).split ('/' )
116
- if name [0 ] == "." or name [0 ] == "" :
117
- name = name [1 :]
118
- for thing in mapfile_beginning :
119
- if name [0 ] == thing :
120
- name = name [1 :]
121
- elif name [0 ] in mapfile_beginning :
122
- pass
110
+ rex_mbed_os_name = r'^.+mbed-os\/(.+)\/(.+\.o)$'
111
+ test_rex_mbed_os_name = re .match (rex_mbed_os_name , txt )
112
+
113
+ if test_rex_mbed_os_name :
114
+
115
+ object_name = test_rex_mbed_os_name .group (2 )
116
+ data = test_rex_mbed_os_name .group (1 ).split ('/' )
117
+ ndata = len (data )
118
+
119
+ if ndata == 1 :
120
+ module_name = data [0 ]
123
121
else :
124
- break
125
- if name [0 ] == "mbed-os" :
126
- name = name [1 :]
127
- if name [0 ] == "features" :
128
- name = name [1 :]
129
- is_lib = RE_LIB_MATCH .match (txt )
130
- if is_lib :
131
- name = ["libraries" , is_lib .group (1 ), is_lib .group (2 )]
132
- return "/" .join (name ), name [- 1 ]
122
+ module_name = data [0 ] + '/' + data [1 ]
123
+
124
+ return [module_name , object_name ]
125
+
126
+ elif self .detailed_misc :
127
+ rex_obj_name = r'^.+\/(.+\.o\)*)$'
128
+ test_rex_obj_name = re .match (rex_obj_name , txt )
129
+ if test_rex_obj_name :
130
+ object_name = test_rex_obj_name .group (1 )
131
+ return ['Misc/' + object_name , "" ]
132
+
133
+ return ['Misc' , "" ]
134
+ else :
135
+ return ['Misc' , "" ]
133
136
134
137
def parse_section_gcc (self , line ):
135
138
""" Parse data from a section of gcc map file
@@ -364,7 +367,15 @@ def search_objects(self, path):
364
367
365
368
path = path .replace ('\\ ' , '/' )
366
369
367
- search_path = os .path .dirname (path )
370
+ # check location of map file
371
+ rex = r'^(.+)' + r'\/(.+\.map)$'
372
+ test_rex = re .match (rex , path )
373
+
374
+ if test_rex :
375
+ search_path = test_rex .group (1 ) + '/mbed-os/'
376
+ else :
377
+ print "Warning: this doesn't look like an mbed project"
378
+ return
368
379
369
380
for root , _ , obj_files in os .walk (search_path ):
370
381
for obj_file in obj_files :
@@ -479,19 +490,11 @@ def generate_table(self, file_desc):
479
490
for i in list (self .print_sections ):
480
491
table .align [i ] = 'r'
481
492
482
- local_modules = {}
483
493
for i in sorted (self .modules ):
484
- module_name = "/" .join (i .split ("/" )[:self .depth ])
485
- local_modules .setdefault (module_name ,
486
- {k : 0 for k in self .print_sections })
487
- for k in self .print_sections :
488
- local_modules [module_name ][k ] += self .modules [i ][k ]
489
-
490
- for i in sorted (local_modules .keys ()):
491
494
row = [i ]
492
495
493
496
for k in self .print_sections :
494
- row .append (local_modules [i ][k ])
497
+ row .append (self . modules [i ][k ])
495
498
496
499
table .add_row (row )
497
500
@@ -572,8 +575,6 @@ def parse(self, mapfile, toolchain):
572
575
toolchain - the toolchain used to create the file
573
576
"""
574
577
575
- self .mapfile = mapfile
576
-
577
578
result = True
578
579
try :
579
580
with open (mapfile , 'r' ) as file_input :
@@ -588,8 +589,9 @@ def parse(self, mapfile, toolchain):
588
589
self .parse_map_file_iar (file_input )
589
590
else :
590
591
result = False
592
+
591
593
self .compute_report ()
592
-
594
+
593
595
except IOError as error :
594
596
print "I/O error({0}): {1}" .format (error .errno , error .strerror )
595
597
result = False
@@ -629,7 +631,6 @@ def main():
629
631
630
632
parser .add_argument ('-d' , '--detailed' , action = 'store_true' , help = 'Displays the elements in "Misc" in a detailed fashion' , required = False )
631
633
632
- parser .add_argument ('--max-depth' , dest = 'max_depth' , type = int , help = 'Displays the elements in "Misc" in a detailed fashion' , required = False , default = None )
633
634
# Parse/run command
634
635
if len (sys .argv ) <= 1 :
635
636
parser .print_help ()
@@ -639,7 +640,7 @@ def main():
639
640
args = parser .parse_args ()
640
641
641
642
# Create memap object
642
- memap = MemapParser (depth = ( args .max_depth or ( MemapParser . MAXDEPTH if args . detailed else 2 )) )
643
+ memap = MemapParser (detailed_misc = args .detailed )
643
644
644
645
# Parse and decode a map file
645
646
if args .file and args .toolchain :
0 commit comments