mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #2918 from theotherjimmy/memap-improvements
Allow max-depth specification in memappull/2958/head
commit
41323855ec
|
@ -20,6 +20,7 @@ RE_ARMCC = re.compile(
|
||||||
RE_IAR = re.compile(
|
RE_IAR = re.compile(
|
||||||
r'^\s+(.+)\s+(zero|const|ro code|inited|uninit)\s'
|
r'^\s+(.+)\s+(zero|const|ro code|inited|uninit)\s'
|
||||||
r'+0x(\w{8})\s+0x(\w+)\s+(.+)\s.+$')
|
r'+0x(\w{8})\s+0x(\w+)\s+(.+)\s.+$')
|
||||||
|
RE_LIB_MATCH = re.compile("^.*/(.*\.a)\((.*)\)$")
|
||||||
|
|
||||||
class MemapParser(object):
|
class MemapParser(object):
|
||||||
"""An object that represents parsed results, parses the memory map files,
|
"""An object that represents parsed results, parses the memory map files,
|
||||||
|
@ -37,13 +38,16 @@ class MemapParser(object):
|
||||||
|
|
||||||
# sections to print info (generic for all toolchains)
|
# sections to print info (generic for all toolchains)
|
||||||
sections = ('.text', '.data', '.bss', '.heap', '.stack')
|
sections = ('.text', '.data', '.bss', '.heap', '.stack')
|
||||||
|
MAXDEPTH = object()
|
||||||
|
|
||||||
def __init__(self, detailed_misc=False):
|
def __init__(self, depth=2):
|
||||||
""" General initialization
|
""" General initialization
|
||||||
"""
|
"""
|
||||||
#
|
|
||||||
self.detailed_misc = detailed_misc
|
self.depth = depth
|
||||||
|
|
||||||
|
self.mapfile = None
|
||||||
|
|
||||||
# list of all modules and their sections
|
# list of all modules and their sections
|
||||||
self.modules = dict()
|
self.modules = dict()
|
||||||
|
|
||||||
|
@ -98,7 +102,7 @@ class MemapParser(object):
|
||||||
else:
|
else:
|
||||||
return False # everything else, means no change in section
|
return False # everything else, means no change in section
|
||||||
|
|
||||||
|
|
||||||
def path_object_to_module_name(self, txt):
|
def path_object_to_module_name(self, txt):
|
||||||
""" Parse a path to object file to extract it's module and object data
|
""" Parse a path to object file to extract it's module and object data
|
||||||
|
|
||||||
|
@ -107,32 +111,25 @@ class MemapParser(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
txt = txt.replace('\\', '/')
|
txt = txt.replace('\\', '/')
|
||||||
rex_mbed_os_name = r'^.+mbed-os\/(.+)\/(.+\.o)$'
|
name = txt.split('/')
|
||||||
test_rex_mbed_os_name = re.match(rex_mbed_os_name, txt)
|
mapfile_beginning = os.path.dirname(self.mapfile).split('/')
|
||||||
|
if name[0] == "." or name[0] == "":
|
||||||
if test_rex_mbed_os_name:
|
name = name[1:]
|
||||||
|
for thing in mapfile_beginning:
|
||||||
object_name = test_rex_mbed_os_name.group(2)
|
if name[0] == thing:
|
||||||
data = test_rex_mbed_os_name.group(1).split('/')
|
name = name[1:]
|
||||||
ndata = len(data)
|
elif name[0] in mapfile_beginning:
|
||||||
|
pass
|
||||||
if ndata == 1:
|
|
||||||
module_name = data[0]
|
|
||||||
else:
|
else:
|
||||||
module_name = data[0] + '/' + data[1]
|
break
|
||||||
|
if name[0] == "mbed-os":
|
||||||
return [module_name, object_name]
|
name = name[1:]
|
||||||
|
if name[0] == "features":
|
||||||
elif self.detailed_misc:
|
name = name[1:]
|
||||||
rex_obj_name = r'^.+\/(.+\.o\)*)$'
|
is_lib = RE_LIB_MATCH.match(txt)
|
||||||
test_rex_obj_name = re.match(rex_obj_name, txt)
|
if is_lib:
|
||||||
if test_rex_obj_name:
|
name = ["libraries", is_lib.group(1), is_lib.group(2)]
|
||||||
object_name = test_rex_obj_name.group(1)
|
return "/".join(name), name[-1]
|
||||||
return ['Misc/' + object_name, ""]
|
|
||||||
|
|
||||||
return ['Misc', ""]
|
|
||||||
else:
|
|
||||||
return ['Misc', ""]
|
|
||||||
|
|
||||||
def parse_section_gcc(self, line):
|
def parse_section_gcc(self, line):
|
||||||
""" Parse data from a section of gcc map file
|
""" Parse data from a section of gcc map file
|
||||||
|
@ -367,15 +364,7 @@ class MemapParser(object):
|
||||||
|
|
||||||
path = path.replace('\\', '/')
|
path = path.replace('\\', '/')
|
||||||
|
|
||||||
# check location of map file
|
search_path = os.path.dirname(path)
|
||||||
rex = r'^(.+)' + r'\/(.+\.map)$'
|
|
||||||
test_rex = re.match(rex, path)
|
|
||||||
|
|
||||||
if test_rex:
|
|
||||||
search_path = test_rex.group(1) + '/mbed-os/'
|
|
||||||
else:
|
|
||||||
print "Warning: this doesn't look like an mbed project"
|
|
||||||
return
|
|
||||||
|
|
||||||
for root, _, obj_files in os.walk(search_path):
|
for root, _, obj_files in os.walk(search_path):
|
||||||
for obj_file in obj_files:
|
for obj_file in obj_files:
|
||||||
|
@ -490,11 +479,19 @@ class MemapParser(object):
|
||||||
for i in list(self.print_sections):
|
for i in list(self.print_sections):
|
||||||
table.align[i] = 'r'
|
table.align[i] = 'r'
|
||||||
|
|
||||||
|
local_modules = {}
|
||||||
for i in sorted(self.modules):
|
for i in sorted(self.modules):
|
||||||
|
module_name = "/".join(i.split("/")[:self.depth])
|
||||||
|
local_modules.setdefault(module_name,
|
||||||
|
{k: 0 for k in self.print_sections})
|
||||||
|
for k in self.print_sections:
|
||||||
|
local_modules[module_name][k] += self.modules[i][k]
|
||||||
|
|
||||||
|
for i in sorted(local_modules.keys()):
|
||||||
row = [i]
|
row = [i]
|
||||||
|
|
||||||
for k in self.print_sections:
|
for k in self.print_sections:
|
||||||
row.append(self.modules[i][k])
|
row.append(local_modules[i][k])
|
||||||
|
|
||||||
table.add_row(row)
|
table.add_row(row)
|
||||||
|
|
||||||
|
@ -575,6 +572,8 @@ class MemapParser(object):
|
||||||
toolchain - the toolchain used to create the file
|
toolchain - the toolchain used to create the file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
self.mapfile = mapfile
|
||||||
|
|
||||||
result = True
|
result = True
|
||||||
try:
|
try:
|
||||||
with open(mapfile, 'r') as file_input:
|
with open(mapfile, 'r') as file_input:
|
||||||
|
@ -589,9 +588,8 @@ class MemapParser(object):
|
||||||
self.parse_map_file_iar(file_input)
|
self.parse_map_file_iar(file_input)
|
||||||
else:
|
else:
|
||||||
result = False
|
result = False
|
||||||
|
|
||||||
self.compute_report()
|
self.compute_report()
|
||||||
|
|
||||||
except IOError as error:
|
except IOError as error:
|
||||||
print "I/O error({0}): {1}".format(error.errno, error.strerror)
|
print "I/O error({0}): {1}".format(error.errno, error.strerror)
|
||||||
result = False
|
result = False
|
||||||
|
@ -631,6 +629,7 @@ def main():
|
||||||
|
|
||||||
parser.add_argument('-d', '--detailed', action='store_true', help='Displays the elements in "Misc" in a detailed fashion', required=False)
|
parser.add_argument('-d', '--detailed', action='store_true', help='Displays the elements in "Misc" in a detailed fashion', required=False)
|
||||||
|
|
||||||
|
parser.add_argument('--max-depth', dest='max_depth', type=int, help='Displays the elements in "Misc" in a detailed fashion', required=False, default=None)
|
||||||
# Parse/run command
|
# Parse/run command
|
||||||
if len(sys.argv) <= 1:
|
if len(sys.argv) <= 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
|
@ -640,7 +639,7 @@ def main():
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Create memap object
|
# Create memap object
|
||||||
memap = MemapParser(detailed_misc=args.detailed)
|
memap = MemapParser(depth=(args.max_depth or (MemapParser.MAXDEPTH if args.detailed else 2)))
|
||||||
|
|
||||||
# Parse and decode a map file
|
# Parse and decode a map file
|
||||||
if args.file and args.toolchain:
|
if args.file and args.toolchain:
|
||||||
|
|
Loading…
Reference in New Issue