2025-10-10 16:07:00 +08:00

157 lines
7.7 KiB
Python
Executable File

#!/usr/bin/python3
import re
import os
import sys
import csv
from collections import OrderedDict
class MapHelper(object):
def __init__(self, map_file_path) -> None:
self.map_file_path = map_file_path
if not os.path.isfile(map_file_path):
print('{0} does not exist'.format(map_file_path))
exit(1)
self.flags = {
'rodata': ['.rodata.', '.rodata', '.srodata.', '.vectors','.vectors_itcm'],
'text': ['.text.', '.text', '.stext.', '.itcm_sec_code','itcm_section', '.itcm', '.iram', '.interrupt'],
'data': ['.data.', '.data', '.sdata.', '.dtcm_sec_data', '.dtcm'],
'bss': ['.bss.', '.bss', '.sbss.', '.dtcm_sec_bss','.bt_spec_data','.ble_bss_data','video_spec_data'],
}
self.size_pat = re.compile(' +0x([a-fA-F\d]+) +0x([a-fA-F\d]+) +(.*)\((.*)\)')
self.oneline_size_pat = re.compile(' +.* +0x([a-fA-F\d]+) +0x([a-fA-F\d]+) +(.*)\((.*)\)')
# 0x00000000 0x8 armino/bk_rtos/libbk_rtos.a(rtos_pub.c.obj)
self.parsed_data = OrderedDict()
def parse_flag(self, line):
striped_line = line.strip()
for (tmp_k, tmp_v) in self.flags.items():
for tmp_flag in tmp_v:
if striped_line.startswith(tmp_flag):
return tmp_k
return None
def add_parse_data(self, flag, size, file_path, obj_name):
if file_path not in self.parsed_data.keys():
self.parsed_data[file_path] = OrderedDict()
if obj_name not in self.parsed_data[file_path].keys():
self.parsed_data[file_path][obj_name] = {
'rodata': 0,
'text': 0,
'data': 0,
'bss': 0
}
self.parsed_data[file_path][obj_name][flag] += size
def start_parse(self):
with open(self.map_file_path, 'r') as f:
tmp_flag = None
for tmp_line in f.readlines():
if tmp_flag is None:
tmp_flag = self.parse_flag(tmp_line)
if tmp_flag is not None:
size_m = re.match(self.oneline_size_pat, tmp_line)
if size_m:
tmp_point_v = size_m.group(1)
if tmp_point_v != '0'*len(tmp_point_v):
#print('bbbbb', size_m.group(1), 'aaaa', tmp_line)
self.add_parse_data(tmp_flag, int(size_m.group(2), 16), size_m.group(3), size_m.group(4))
tmp_flag = None
else:
# parse size
size_m = re.match(self.size_pat, tmp_line)
if size_m:
#print(size_m.group(1))
tmp_point_v = size_m.group(1)
if tmp_point_v != '0'*len(tmp_point_v):
# print('aaaaa', size_m.group(1))
self.add_parse_data(tmp_flag, int(size_m.group(2), 16), size_m.group(3), size_m.group(4))
# clear flag content
tmp_flag = None
def format_title_line(self):
return '{0} {1} {2} {3} {4} {5} {6} {7}\n'.format('text'.rjust(7), 'code'.rjust(7), 'rodata'.rjust(7), 'data'.rjust(7), 'bss'.rjust(7), 'dec'.rjust(7), 'hex'.rjust(7), 'filename')
def format_size_line(self, code_size, rodata_size, data_size, bss_size, filename, obj_name):
text_size = code_size + rodata_size
dec_size = text_size + data_size + bss_size
hex_size = hex(dec_size)[2:]
return ([text_size, code_size, rodata_size, data_size, bss_size, dec_size, '`'+str(hex_size), obj_name + ' (ex ' + filename + ')', filename],
'{0} {1} {2} {3} {4} {5} {6} {7}\n'.format(
str(text_size).rjust(7),
str(code_size).rjust(7),
str(rodata_size).rjust(7),
str(data_size).rjust(7),
str(bss_size).rjust(7),
str(dec_size).rjust(7),
hex_size.rjust(7),
obj_name + ' (ex ' + filename + ')'
))
def format_total_size_line(self, code_size, rodata_size, data_size, bss_size, filename):
text_size = code_size + rodata_size
dec_size = text_size + data_size + bss_size
hex_size = hex(dec_size)[2:]
return ( [text_size, code_size, rodata_size, data_size, bss_size, dec_size, '`'+str(hex_size), filename] ,
'{0} {1} {2} {3} {4} {5} {6} {7}\n'.format(
str(text_size).rjust(7),
str(code_size).rjust(7),
str(rodata_size).rjust(7),
str(data_size).rjust(7),
str(bss_size).rjust(7),
str(dec_size).rjust(7),
hex_size.rjust(7),
filename
))
def save_to_file(self):
with open(os.path.join(os.path.dirname(self.map_file_path), 'size_map.txt'), 'w') as f:
with open(os.path.join(os.path.dirname(self.map_file_path), 'size_map_total.csv'), 'w', newline='') as f_csv:
csv_writer = csv.writer(f_csv)
csv_writer.writerow(['text', 'code', 'rodata', 'data', 'bss', 'dec', 'hex', 'filename'])
with open(os.path.join(os.path.dirname(self.map_file_path), 'size_map_detail.csv'), 'w', newline='') as f_csv_detail:
csv_detail_writer = csv.writer(f_csv_detail)
csv_detail_writer.writerow(['text', 'code', 'rodata', 'data', 'bss', 'dec', 'hex', 'filename', 'filename'])
for tmp_file in self.parsed_data.keys():
tmp_total = {
'text': 0,
'rodata': 0,
'data': 0,
'bss': 0,
}
f.write(self.format_title_line())
for tmp_obj in self.parsed_data[tmp_file].keys():
#if tmp_obj == "sys_hal.c.obj":
# print("==========="+self.parsed_data[tmp_file][tmp_obj]['text'])
tmp_total['text'] += self.parsed_data[tmp_file][tmp_obj]['text']
tmp_total['rodata'] += self.parsed_data[tmp_file][tmp_obj]['rodata']
tmp_total['data'] += self.parsed_data[tmp_file][tmp_obj]['data']
tmp_total['bss'] += self.parsed_data[tmp_file][tmp_obj]['bss']
(detail_csv_tmp, detail_tmp) = self.format_size_line(
self.parsed_data[tmp_file][tmp_obj]['text'],
self.parsed_data[tmp_file][tmp_obj]['rodata'],
self.parsed_data[tmp_file][tmp_obj]['data'],
self.parsed_data[tmp_file][tmp_obj]['bss'],
tmp_file,
tmp_obj
)
f.write(detail_tmp)
csv_detail_writer.writerow(detail_csv_tmp)
(csv_tmp, total_tmp) = self.format_total_size_line(tmp_total['text'], tmp_total['rodata'], tmp_total['data'], tmp_total['bss'], tmp_file)
f.write(total_tmp)
f.write('\n')
csv_writer.writerow(csv_tmp)
csv_tmp.append(csv_tmp[-1])
csv_detail_writer.writerow(csv_tmp)
if __name__ == '__main__':
print(sys.argv)
map_file_path = sys.argv[1]
mh = MapHelper(map_file_path=map_file_path)
mh.start_parse()
mh.save_to_file()