@@ -50,12 +50,11 @@ class MemapParser(object):
50
50
sections = ('.text' , '.data' , '.bss' , '.heap' , '.stack' )
51
51
52
52
def __init__ (self ):
53
- """ General initialization
54
- """
55
-
56
53
# list of all modules and their sections
57
- self .modules = dict () # full list - doesn't change with depth
58
- self .short_modules = dict () # short version with specific depth
54
+ # full list - doesn't change with depth
55
+ self .modules = dict ()
56
+ # short version with specific depth
57
+ self .short_modules = dict ()
59
58
60
59
# sections must be defined in this order to take irrelevant out
61
60
self .all_sections = self .sections + self .other_sections + \
@@ -64,27 +63,27 @@ def __init__(self):
64
63
# Memory report (sections + summary)
65
64
self .mem_report = []
66
65
67
- # Just the memory summary section
66
+ # Memory summary
68
67
self .mem_summary = dict ()
69
68
69
+ # Totals of ".text", ".data" and ".bss"
70
70
self .subtotal = dict ()
71
71
72
+ # Flash no associated with a module
72
73
self .misc_flash_mem = 0
73
74
74
75
# Modules passed to the linker on the command line
75
76
# this is a dict because modules are looked up by their basename
76
77
self .cmd_modules = {}
77
78
78
-
79
79
def module_add (self , object_name , size , section ):
80
- """ Adds a module / section to the list
80
+ """ Adds a module or section to the list
81
81
82
82
Positional arguments:
83
83
object_name - name of the entry to add
84
84
size - the size of the module being added
85
85
section - the section the module contributes to
86
86
"""
87
-
88
87
if not object_name or not size or not section :
89
88
return
90
89
@@ -117,7 +116,6 @@ def check_new_section_gcc(self, line):
117
116
Positional arguments:
118
117
line - the line to check for a new section
119
118
"""
120
-
121
119
for i in self .all_sections :
122
120
if line .startswith (i ):
123
121
# should name of the section (assuming it's a known one)
@@ -135,11 +133,9 @@ def parse_object_name_gcc(self, line):
135
133
Positional arguments:
136
134
txt - the path to parse the object and module name from
137
135
"""
138
-
139
136
test_re_mbed_os_name = re .match (RE_OBJECT_FILE_GCC , line )
140
137
141
138
if test_re_mbed_os_name :
142
-
143
139
object_name = test_re_mbed_os_name .group (1 )
144
140
145
141
# corner case: certain objects are provided by the GCC toolchain
@@ -148,15 +144,12 @@ def parse_object_name_gcc(self, line):
148
144
return object_name
149
145
150
146
else :
151
-
152
147
test_re_obj_name = re .match (RE_LIBRARY_OBJECT_GCC , line )
153
148
154
149
if test_re_obj_name :
155
150
object_name = os .path .join (test_re_obj_name .group (1 ),
156
151
test_re_obj_name .group (2 ))
157
-
158
152
return os .path .join ('[lib]' , object_name )
159
-
160
153
else :
161
154
print "Unknown object name found in GCC map file: %s" % line
162
155
return '[misc]'
@@ -171,7 +164,6 @@ def parse_section_gcc(self, line):
171
164
Positional arguments:
172
165
line - the line to parse a section from
173
166
"""
174
-
175
167
is_fill = re .match (RE_FILL_SECTION_GCC , line )
176
168
if is_fill :
177
169
o_name = '[fill]'
@@ -193,7 +185,6 @@ def parse_map_file_gcc(self, file_desc):
193
185
Positional arguments:
194
186
file_desc - a stream object to parse as a gcc map file
195
187
"""
196
-
197
188
current_section = 'unknown'
198
189
199
190
with file_desc as infile :
@@ -211,7 +202,6 @@ def parse_map_file_gcc(self, file_desc):
211
202
current_section = next_section
212
203
213
204
object_name , object_size = self .parse_section_gcc (line )
214
-
215
205
self .module_add (object_name , object_size , current_section )
216
206
217
207
common_prefix = os .path .dirname (os .path .commonprefix ([
@@ -232,9 +222,7 @@ def parse_object_name_armcc(self, line):
232
222
Positional arguments:
233
223
line - the line containing the object or library
234
224
"""
235
-
236
- # simple object (not library)
237
- if line [- 2 ] == '.' and line [- 1 ] == 'o' :
225
+ if line .endswith (".o" ):
238
226
return line
239
227
240
228
else :
@@ -247,8 +235,6 @@ def parse_object_name_armcc(self, line):
247
235
print "Malformed input found when parsing ARMCC map: %s" % line
248
236
return '[misc]'
249
237
250
-
251
-
252
238
def parse_section_armcc (self , line ):
253
239
""" Parse data from an armcc map file
254
240
@@ -260,11 +246,9 @@ def parse_section_armcc(self, line):
260
246
Positional arguments:
261
247
line - the line to parse the section data from
262
248
"""
263
-
264
249
test_re_armcc = re .match (RE_ARMCC , line )
265
250
266
251
if test_re_armcc :
267
-
268
252
size = int (test_re_armcc .group (2 ), 16 )
269
253
270
254
if test_re_armcc .group (4 ) == 'RO' :
@@ -283,7 +267,7 @@ def parse_section_armcc(self, line):
283
267
return ["" , 0 , "" ]
284
268
285
269
# check name of object or library
286
- object_name = self .parse_object_name_armcc (\
270
+ object_name = self .parse_object_name_armcc (
287
271
test_re_armcc .group (6 ))
288
272
289
273
return [object_name , size , section ]
@@ -297,8 +281,6 @@ def parse_object_name_iar(self, object_name):
297
281
Positional arguments:
298
282
line - the line containing the object or library
299
283
"""
300
-
301
- # simple object (not library)
302
284
if object_name .endswith (".o" ):
303
285
try :
304
286
return self .cmd_modules [object_name ]
@@ -307,7 +289,6 @@ def parse_object_name_iar(self, object_name):
307
289
else :
308
290
return '[misc]'
309
291
310
-
311
292
def parse_section_iar (self , line ):
312
293
""" Parse data from an IAR map file
313
294
@@ -325,13 +306,8 @@ def parse_section_iar(self, line):
325
306
Positional_arguments:
326
307
line - the line to parse section data from
327
308
"""
328
-
329
309
test_re_iar = re .match (RE_IAR , line )
330
-
331
310
if test_re_iar :
332
-
333
- size = int (test_re_iar .group (4 ), 16 )
334
-
335
311
if (test_re_iar .group (2 ) == 'const' or
336
312
test_re_iar .group (2 ) == 'ro code' ):
337
313
section = '.text'
@@ -348,24 +324,24 @@ def parse_section_iar(self, line):
348
324
section = '.data'
349
325
else :
350
326
print "Malformed input found when parsing IAR map: %s" % line
327
+ return ["" , 0 , "" ]
351
328
352
329
# lookup object in dictionary and return module name
353
330
object_name = self .parse_object_name_iar (test_re_iar .group (5 ))
354
331
332
+ size = int (test_re_iar .group (4 ), 16 )
355
333
return [object_name , size , section ]
356
334
357
335
else :
358
- return ["" , 0 , "" ] # no valid entry
336
+ return ["" , 0 , "" ]
359
337
360
338
def parse_map_file_armcc (self , file_desc ):
361
339
""" Main logic to decode armc5 map files
362
340
363
341
Positional arguments:
364
342
file_desc - a file like object to parse as an armc5 map file
365
343
"""
366
-
367
344
with file_desc as infile :
368
-
369
345
# Search area to parse
370
346
for line in infile :
371
347
if line .startswith (' Base Addr Size' ):
@@ -387,18 +363,13 @@ def parse_map_file_armcc(self, file_desc):
387
363
new_modules [name ] = stats
388
364
self .modules = new_modules
389
365
390
-
391
-
392
366
def check_new_library_iar (self , line ):
393
367
"""
394
368
Searches for libraries and returns name. Example:
395
369
m7M_tls.a: [43]
396
370
397
371
"""
398
-
399
-
400
372
test_address_line = re .match (RE_LIBRARY_IAR , line )
401
-
402
373
if test_address_line :
403
374
return test_address_line .group (1 )
404
375
else :
@@ -415,9 +386,7 @@ def check_new_object_lib_iar(self, line):
415
386
I64DivZer.o 2
416
387
417
388
"""
418
-
419
389
test_address_line = re .match (RE_OBJECT_LIBRARY_IAR , line )
420
-
421
390
if test_address_line :
422
391
return test_address_line .group (1 )
423
392
else :
@@ -447,7 +416,6 @@ def parse_map_file_iar(self, file_desc):
447
416
Positional arguments:
448
417
file_desc - a file like object to parse as an IAR map file
449
418
"""
450
-
451
419
with file_desc as infile :
452
420
self .parse_iar_command_line (infile )
453
421
@@ -463,7 +431,6 @@ def parse_map_file_iar(self, file_desc):
463
431
464
432
current_library = ""
465
433
for line in infile :
466
-
467
434
library = self .check_new_library_iar (line )
468
435
469
436
if library :
@@ -475,7 +442,6 @@ def parse_map_file_iar(self, file_desc):
475
442
temp = os .path .join ('[lib]' , current_library , object_name )
476
443
self .module_replace (object_name , temp )
477
444
478
-
479
445
def reduce_depth (self , depth ):
480
446
"""
481
447
populates the short_modules attribute with a truncated module list
@@ -504,7 +470,6 @@ def reduce_depth(self, depth):
504
470
self .short_modules [new_name ].setdefault (section_idx , 0 )
505
471
self .short_modules [new_name ][section_idx ] += self .modules [module_name ][section_idx ]
506
472
507
-
508
473
export_formats = ["json" , "csv-ci" , "table" ]
509
474
510
475
def generate_output (self , export_format , depth , file_output = None ):
@@ -519,10 +484,8 @@ def generate_output(self, export_format, depth, file_output=None):
519
484
520
485
Returns: generated string for the 'table' format, otherwise None
521
486
"""
522
-
523
487
self .reduce_depth (depth )
524
488
self .compute_report ()
525
-
526
489
try :
527
490
if file_output :
528
491
file_desc = open (file_output , 'wb' )
@@ -550,7 +513,6 @@ def generate_json(self, file_desc):
550
513
"""
551
514
file_desc .write (json .dumps (self .mem_report , indent = 4 ))
552
515
file_desc .write ('\n ' )
553
-
554
516
return None
555
517
556
518
def generate_csv (self , file_desc ):
@@ -577,7 +539,6 @@ def generate_csv(self, file_desc):
577
539
578
540
csv_writer .writerow (csv_module_section )
579
541
csv_writer .writerow (csv_sizes )
580
-
581
542
return None
582
543
583
544
def generate_table (self , file_desc ):
@@ -659,7 +620,6 @@ def parse(self, mapfile, toolchain):
659
620
mapfile - the file name of the memory map file
660
621
toolchain - the toolchain used to create the file
661
622
"""
662
-
663
623
result = True
664
624
try :
665
625
with open (mapfile , 'r' ) as file_input :
@@ -679,7 +639,6 @@ def parse(self, mapfile, toolchain):
679
639
680
640
def main ():
681
641
"""Entry Point"""
682
-
683
642
version = '0.4.0'
684
643
685
644
# Parser handling
0 commit comments