1#!/usr/bin/env python3 2# coding=utf-8 3# Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import json 17import os 18import sys 19from os.path import join, isdir, abspath, exists, isabs, sep, normpath 20import re 21 22from common_utils import CommonUtils 23 24work_dir = os.path.split(os.path.realpath(__file__))[0] 25root_dir = os.path.join(work_dir, '..', '..', '..') 26sys.path.append(os.path.join(root_dir, 'build')) 27sys.path.append(os.path.join(root_dir, 'build', 'script')) 28sys.path.append(os.path.join(root_dir, 'build', 'config')) 29from enviroment import TargetEnvironment 30from utils.build_utils import output_root 31 32map_start_rule = r'Memory Configuration' 33map_end_rule = r'Linker script and memory map' 34# map文件中Cross Reference Table项不涉及镜像大小,结束map文件解析 35map_file_size_end = r"Cross Reference Table" 36elf_setion_rule = r'^\s[0-9]' 37elf_symbol_rule = r'^[0-9]+' 38file_size_content_rule = r'^(\s*\.[a-zA-Z]+)' 39 40 41class BuildDataAnalyzer: 42 _elf_path = '' 43 _map_path = '' 44 _build_config_path = '' 45 _module_config = {} 46 _compiler_path = '' 47 _prefix = 'arm-none-eabi' 48 _section_keys = [] 49 _environment = '' 50 51 section_data = {} 52 region_data = [] 53 size_data = {} 54 elf_size_data = {} 55 module_data = {} 56 folder_data = {} 57 rom_addr = { 58 'start': 0, 59 'end': 0 60 } 61 rom_parts = {} 62 is_rom = True 63 last_symbol = [] 64 last_line = '' 65 is_unknown = False 66 cur_section = '' 67 cur_section_size = '' 68 69 def __init__(self, paths): 70 print('++++++++++start buildAnalyzer++++++++++') 71 data = CommonUtils.get_prefix(paths['compiler_path']) 72 self._prefix = data['prefix'] 73 self._environment = data['environment'] 74 for key, value in paths.items(): 75 print(f"{key}:{value}") 76 self._elf_path = paths['elf_path'] 77 self._map_path = paths['map_path'] 78 self._compiler_path = paths['compiler_path'] 79 self._build_config_path = paths['build_config_path'] 80 self._remove_sections_config_path = paths['remove_sections_config_path'] 81 self._result_save_path = paths['result_save_path'] 82 83 try: 84 save_dir = os.path.dirname(self._result_save_path) 85 if not os.path.isdir(save_dir): 86 os.makedirs(save_dir) 87 except Exception as e: 88 raise Exception(f"Failed to Create Save Directory,{e}") 89 self._root_dir = os.getcwd() 90 self._json_path = join(self._root_dir, 'memoryDetails.json') 91 self._image_remove_section = [] 92 93 def do_build_analysis(self, paths): 94 try: 95 with open(self._remove_sections_config_path, 'r') as rv_f: 96 for line in rv_f.readlines(): 97 l_s = line.strip() 98 self._image_remove_section.append(l_s) 99 100 self._module_config = self._get_build_json(paths.get('build_config_path', "")) 101 json_obj = self._parse_map_file() 102 self.result_filter(json_obj) 103 # with open(self._result_save_path, 'w') as result_f: 104 # json.dump(json_obj, result_f, indent=4) 105 print('++++++++++end buildAnalyzer++++++++++') 106 except Exception as e: 107 raise Exception('buildAnalyzer error') from e 108 109 def result_filter(self, json_cont): 110 """ 111 结果过滤 112 """ 113 new_json = json_cont.get("moduleData", "") 114 if not new_json: 115 raise Exception("ImageAnalysis Failed") 116 with open(self._result_save_path, 'w') as res_f: 117 res_f.write('<h1>Image Analysis</h1>') 118 res_f.write('<table border="1" width = "40%" cellspacing="0" cellpadding="0" align="left">') 119 line = 0 120 for key, value in new_json.items(): 121 if line == 0: 122 head_line = '<tr>' 123 for v in value: 124 if v == 'parent': 125 continue 126 head_line = head_line + '<th>' + v + '</th>' 127 head_line = head_line + '<tr>\n' 128 res_f.write(head_line) 129 line = line + 1 130 new_line = '<tr>' 131 if value["parent"]: 132 continue 133 for v in value: 134 if value[v] != '': 135 new_line = new_line + '<td>' + str(value[v]) + '</td>' 136 new_line = new_line + '</tr>\n' 137 res_f.write(new_line) 138 139 @staticmethod 140 def _get_build_json(file_path): 141 try: 142 with open(file_path, 'r', encoding='utf-8') as f: 143 res = f.read() 144 json_data = json.loads(s=res) 145 return json_data 146 except FileExistsError as e: 147 print('file exists error') 148 raise FileExistsError() from e 149 150 def _parse_map_file(self): 151 try: 152 suffix = self._prefix + '-size.exe' 153 if self._environment == 'linux': 154 suffix = self._prefix + '-size' 155 file_size_path = join(self._compiler_path, suffix) 156 if not exists(file_size_path): 157 print(f'size path not find: {file_size_path}') 158 raise FileExistsError() 159 size_arr = self.get_file_size(file_size_path, '-A', self._elf_path) 160 size_arr.pop() 161 size_arr.pop(0) 162 self._set_elf_size_data(size_arr) 163 json_obj = self._read_file() 164 return json_obj 165 except SystemError as e: 166 print('map parse error') 167 raise SystemError() from e 168 169 def _set_elf_size_data(self, size_arr): 170 order_section_keys = [".text", ".data", ".bss", ".reboot_retention"] 171 order_elf_size_data = dict() 172 for key in order_section_keys: 173 order_elf_size_data[key] = {'addr': None, 'size': None} 174 175 for item in size_arr: 176 elf_key, elf_size, elf_addr = re.sub(r'\s+', ' ', item).split(' ')[:3] 177 if elf_key.startswith('.') and (elf_size != '0' or elf_addr != '0'): 178 order_elf_size_data[elf_key] = {'addr': int(elf_addr), 'size': int(elf_size)} 179 if elf_key not in order_section_keys: 180 order_section_keys.append(elf_key) 181 self._section_keys = list() 182 for k, v in order_elf_size_data.items(): 183 if v.get("size", None) is None: 184 continue 185 if k in self._image_remove_section: 186 continue 187 self.elf_size_data[k] = v 188 self._section_keys.append(k) 189 190 def _read_file(self): 191 try: 192 self._read_file_to_arr() 193 json_obj = self._parse_elf_file(self._elf_path) 194 return json_obj 195 except Exception as e: 196 print('elf parse error') 197 raise Exception() from e 198 199 def _parse_elf_file(self, elf_path): 200 suffix = self._prefix + '-objdump.exe' 201 if self._environment == 'linux': 202 suffix = self._prefix + '-objdump' 203 obj_dump_path = join(self._compiler_path, suffix) 204 if not obj_dump_path or not exists(obj_dump_path): 205 print('Please configure the correct compiler type and compiler path') 206 raise FileExistsError() 207 try: 208 data = CommonUtils.get_obj_dump_info(obj_dump_path, '-h', elf_path) 209 self._set_section(data) 210 json_obj = self._get_symbol_data(obj_dump_path, elf_path) 211 return json_obj 212 except SystemError as e: 213 print('elf parse error') 214 raise SystemError() from e 215 216 def _set_section(self, data): 217 for key, value in enumerate(data): 218 line = re.sub(r'\s+', ' ', value) 219 if re.search(elf_setion_rule, line): 220 data_arr = line.split(' ') 221 if len(data_arr) > 2 and data_arr[2] in self._image_remove_section: 222 continue 223 next_line = '' 224 if self._prefix != 'llvm' and key < len(data) - 1: 225 next_line = data[key + 1] 226 self._set_section_data(data_arr, next_line) 227 228 def _set_section_data(self, data_arr, next_line): 229 size = int('0x' + data_arr[3], 16) 230 vma = int('0x' + data_arr[4], 16) 231 if vma > 0 or size != 0: 232 lma = 0 233 if next_line: 234 lma = 0 if next_line.find('LOAD') < 0 else int('0x' + data_arr[5], 16) 235 elif data_arr[5]: 236 lma = int('0x' + data_arr[5], 16) 237 region_name = [] 238 for region_item in self.region_data: 239 start_addr = int(region_item['startAddr'], 16) 240 end_addr = int(region_item['endAddr'], 16) 241 if (start_addr <= vma < end_addr) or (lma != 0 and start_addr <= lma < end_addr): 242 region_name.append(region_item['name']) 243 region_item['used'] += size 244 section = { 245 'regionName': region_name, 246 'runAddr': '0x' + data_arr[4], 247 'loadAddr': '0x' + data_arr[5] if lma else '', 248 'size': self._addr_to_size('0x' + data_arr[3]), 249 'sizeOri': '0x' + data_arr[3], 250 'children': [] 251 } 252 self.section_data[data_arr[2]] = section 253 254 def _get_symbol_data(self, obj_dump_path, elf_path): 255 try: 256 data = CommonUtils.get_obj_dump_info(obj_dump_path, '-t', elf_path) 257 for item in data: 258 line = re.sub(r'\s+', ' ', item) 259 if re.search(elf_symbol_rule, line): 260 self._set_section_symbol_data(line) 261 except SystemError as e: 262 print('data parse error') 263 raise SystemError() from e 264 265 for region in self.region_data: 266 used = self._addr_to_size(hex(region['used'])) 267 try: 268 usage = region['used'] / region['size'] 269 region['usage'] = '%.2f' % (usage * 100) + '%' 270 except ZeroDivisionError: 271 region['usage'] = '0.00%' 272 region['free'] = self._addr_to_size(hex(region['size'] - region['used'])) 273 region['used'] = used 274 region['size'] = self._addr_to_size(hex(region['size'])) 275 json_obj = { 276 'region': self.region_data, 277 'details': self.section_data, 278 'sizeData': self.size_data, 279 'moduleData': self.module_data, 280 'folderData': self.folder_data 281 } 282 return json_obj 283 284 def _set_section_symbol_data(self, line): 285 data_arr = line.split(' ') 286 section_name = data_arr[3] 287 symbol_name = data_arr[-2] 288 type_name = data_arr[2] 289 if len(data_arr[-1]) != 0: 290 symbol_name = data_arr[-1] 291 if section_name != symbol_name and section_name in self.section_data: 292 section = self.section_data[section_name] 293 vma = int('0x' + data_arr[0], 16) 294 lma = 0 295 if section['loadAddr']: 296 lma = int(section['loadAddr'], 16) - int(section['runAddr'], 16) + vma 297 symbol = { 298 'name': symbol_name, 299 'runAddr': '0x' + data_arr[0], 300 'loadAddr': hex(lma) if lma else '', 301 'size': self._addr_to_size('0x' + data_arr[4]), 302 'sizeOri': '0x' + data_arr[4], 303 'location': '', 304 'type': type_name 305 } 306 self.section_data[section_name]['children'].append(symbol) 307 308 @staticmethod 309 def _addr_to_size(addr): 310 size = int(addr, 16) 311 if size < 1024: 312 return f'{size} B' 313 else: 314 return '%.2f' % (size / 1024) + 'KB' 315 316 @staticmethod 317 def get_file_size(file_size_path, arg, elf_file_path): 318 cmd = [file_size_path, arg, elf_file_path] 319 data = CommonUtils.exec_cmd(cmd) 320 return data.strip().split('\n') 321 322 def _read_file_to_arr(self): 323 is_start = False 324 is_end = False 325 with open(self._map_path, 'r') as f: 326 line = f.readline() 327 while line: 328 line = line.strip() 329 if line == map_file_size_end: 330 break 331 if re.match(map_start_rule, line): 332 is_start = True 333 elif re.match(map_end_rule, line): 334 is_end = True 335 elif is_start and not is_end: 336 self._set_region_data(line) 337 elif is_end: 338 self._parse_size_data(line) 339 line = f.readline() 340 341 def _set_region_data(self, line): 342 if len(line) > 0 and not line.startswith('Name') and not line.startswith('*default*'): 343 line_arr = re.sub(r'\s+', ' ', line).split(' ') 344 end_addr = '0x%08x' % (int(line_arr[1], 16) + int(line_arr[2], 16)) 345 if len(line_arr) >= 3: 346 region = { 347 'name': line_arr[0], 348 'startAddr': line_arr[1], 349 'endAddr': end_addr, 350 'size': int(line_arr[2], 16), 351 'sizeOri': line_arr[2], 352 'used': 0, 353 'usage': 0 354 } 355 self.region_data.append(region) 356 name_sp = line_arr[0].split("_") 357 if 'FLASH' in name_sp or "ROM" in name_sp: 358 self.rom_parts[line_arr[0]] = {'start': int(region['startAddr'], 16), 359 'end': int(region['endAddr'], 16)} 360 361 def _parse_size_data(self, line): 362 is_need_parse = False 363 file_size_content_end_rule = re.compile(r'0x[0-9a-fA-F]{8,16}\s+0x[0-9a-fA-F]{1,16}\s+') 364 file_size_symbol_rule = re.compile(r'^(\s*0x[0-9a-fA-F]{8,16})\s*\w+') 365 file_rule = re.compile(r'^(\s+\*fill\*)\s+0x[0-9a-fA-F]{8,16}\s+0x[0-9a-fA-F]{1,16}') 366 is_content_rule = len(line) > 0 and re.search(file_size_content_rule, line) is not None 367 is_end_rule = line.find('.o') > 0 and re.search(file_size_content_end_rule, line) is not None 368 if is_content_rule and is_end_rule: 369 is_need_parse = True 370 elif is_content_rule: 371 self.last_line = line 372 is_need_parse = False 373 elif len(line) > 0 and is_end_rule: 374 line = self.last_line + ' ' + line 375 self.last_line = '' 376 is_need_parse = True 377 elif re.search(file_rule, line) is not None: 378 self.last_line = '' 379 is_need_parse = True 380 else: 381 self.last_line = '' 382 if is_need_parse: 383 if self.is_unknown and len(self.last_symbol) > 1 and self.last_symbol[0]['addr'] in self.size_data: 384 self._reset_symbol_size_data() 385 self.is_unknown = False 386 line = line.strip() 387 line_arr = re.sub(r'\s+', ' ', line).split(' ') 388 for rv_s in self._image_remove_section: 389 if line_arr[0].startswith(rv_s): 390 return 391 addr = line_arr[1] 392 self._get_cur_section(addr) 393 if self.cur_section: 394 self._calculate_size_data(line_arr, addr) 395 elif self.is_unknown and re.search(file_size_symbol_rule, line): 396 line_arr = re.sub(r'\s+', ' ', line).split(' ') 397 addr = line_arr[0] 398 name = line_arr[1] 399 if len(self.last_symbol) == 1 and self.last_symbol[0]['addr'] != addr: 400 self.is_unknown = False 401 self.last_symbol = [] 402 else: 403 self.last_symbol.append({ 404 'addr': addr, 405 'name': name 406 }) 407 408 def _calculate_size_data(self, line_arr, addr): 409 cur_size = int(line_arr[2], 16) 410 # .o或者.obj文件路径相对路径,包含括号里,可能没有.a文件一定有.o/.obj文件 411 # 如 ../../../../interim_binary/brandy/libs/media/evb_standard/libaudio_player.a(liteplayer.cpp.obj) 412 nor_path = normpath(line_arr[3]) 413 a_file_index = nor_path.find('.a(') 414 if nor_path and a_file_index > 0: 415 a_file_path = nor_path[0: a_file_index + 2] 416 a_file_dir = os.path.dirname(a_file_path) 417 a_file_name = os.path.basename(a_file_path) 418 o_file_name = nor_path[a_file_index + 3: len(nor_path) - 1] 419 o_file_dir = a_file_path 420 # 统计.a文件大小 421 param_size = dict(name=a_file_name, 422 parent='', 423 path=a_file_dir, 424 obj_name=o_file_name, 425 lib_name=a_file_name, 426 cur_size=cur_size) 427 self._set_size_data(param_size) 428 # 统计.o/.obj文件大小 429 param_size = dict(name=o_file_name, 430 parent=a_file_name, 431 path=o_file_dir, 432 obj_name=o_file_name, 433 lib_name=a_file_name, 434 cur_size=cur_size) 435 self._set_size_data(param_size) 436 437 else: 438 o_file_name = os.path.basename(nor_path) 439 o_file_dir = os.path.dirname(nor_path) 440 param_size = dict(name=o_file_name, parent='', path=o_file_dir, 441 obj_name=o_file_name, lib_name='', cur_size=cur_size) 442 self._set_size_data(param_size) 443 444 # 函数 445 child = line_arr[0] + ':' + addr 446 self._set_addr_data(addr) 447 if cur_size != 0: 448 param_size.update({'name': child, 'parent': o_file_name, 'path': ''}) 449 self._set_size_data(param_size, True) 450 451 def _set_addr_data(self, addr): 452 if addr in self.size_data: 453 old_size = self.size_data[addr][self.cur_section_size] 454 old_lib = self.size_data[addr]['lib'] 455 old_parent = self.size_data[addr]['parent'] 456 old_module_name = self.size_data[addr]['moduleName'] 457 old_component_name = self.size_data[addr]['componentName'] 458 if old_lib in self.size_data: 459 self.size_data[old_lib][self.cur_section_size] = self.size_data[ 460 old_lib][self.cur_section_size] - old_size 461 462 if old_parent in self.size_data: 463 self.size_data[old_parent][self.cur_section_size] = self.size_data[ 464 old_parent][self.cur_section_size] - old_size 465 self._set_old_parent_size(old_parent, old_size) 466 467 if old_module_name in self.module_data: 468 self.module_data[old_module_name][self.cur_section_size] = self.module_data[ 469 old_module_name][ 470 self.cur_section_size] - old_size 471 472 if old_component_name in self.module_data: 473 self.module_data[old_component_name][self.cur_section_size] = self.module_data[ 474 old_component_name][ 475 self.cur_section_size] - old_size 476 477 def _set_old_parent_size(self, cur_parent, cur_size): 478 if self.size_data[cur_parent]['parent'] == '' and 'path' in self.size_data[cur_parent]: 479 path_list = self.size_data[cur_parent]['path'].split(sep) 480 temp_folder = self.folder_data 481 for path in path_list: 482 if path in temp_folder and self.cur_section_size in temp_folder[path]: 483 temp_folder[path][self.cur_section_size] = temp_folder[path][self.cur_section_size] - cur_size 484 temp_folder = temp_folder[path] 485 486 def _set_size_data(self, param_size, is_symbol=False): 487 # .a/.o/.obj文件的索引字符串:全路径 488 name = param_size.get('name') 489 # .o/.obj是否有父节点.a文件 490 parent = param_size.get('parent') 491 # .o/.obj文件名称 492 obj_name = param_size.get('obj_name') 493 # .a文件名称 494 lib_name = param_size.get('lib_name') 495 # .o/.obj文件大小 496 cur_size = param_size.get('cur_size') 497 # .a/.o/.obj文件的目录 498 file_dir = param_size.get('path') 499 if name in self.size_data and not is_symbol: 500 if not self.size_data[name][self.cur_section_size]: 501 self.size_data[name][self.cur_section_size] = cur_size 502 else: 503 self.size_data[name][self.cur_section_size] = self.size_data[name][self.cur_section_size] + cur_size 504 elif name: 505 symbol_name = name.split(':')[0] 506 name = symbol_name 507 self.size_data[name] = { 508 'objName': symbol_name, 509 'parent': parent, 510 'path': file_dir, 511 'romSize': 0, 512 'moduleName': self._get_module_name(obj_name), 513 'componentName': self._get_component_name(lib_name) 514 } 515 if is_symbol: 516 self.size_data[name]['isSymbol'] = True 517 self.size_data[name]['lib'] = lib_name 518 self._set_module_data(self.size_data[name]['moduleName'], self.size_data[name]['componentName'], 519 cur_size) 520 self._set_module_data(self.size_data[name]['componentName'], '', cur_size) 521 if self.size_data[name]['moduleName'] == '' and self.size_data[name]['componentName']: 522 self.size_data[name]['moduleName'] = self.size_data[name]['componentName'] 523 for item in self._section_keys: 524 self.size_data[name][item] = 0 525 self.size_data[name][self.cur_section_size] = cur_size 526 if self.is_rom and name: 527 self.size_data[name]['romSize'] = self.size_data[name]['romSize'] + cur_size 528 529 if file_dir and not isabs(file_dir): 530 self._set_folder_data(file_dir, name, cur_size, obj_name) 531 532 def _set_folder_data(self, cur_path, cur_name, cur_size, child_name): 533 """ 534 Split paths and assemble them into dict 535 Example: "build/libs/main.o" assemble to {"build":{"child":[], "size":1, "libs"{"child":[main.o], "size":1}}} 536 """ 537 path_list = cur_path.split(sep) 538 temp_folder = self.folder_data 539 540 for path in path_list: 541 self._set_child_size(path, temp_folder, cur_size, []) 542 temp_folder = temp_folder[path] 543 544 if cur_name not in temp_folder['child']: 545 if cur_name != child_name: 546 self._set_child_size(cur_name, temp_folder, cur_size, [child_name]) 547 if cur_name in temp_folder and child_name not in temp_folder[cur_name]['child']: 548 temp_folder[cur_name]['child'].append(child_name) 549 else: 550 temp_folder['child'].append(cur_name) 551 552 def _set_child_size(self, cur, folder, size, child_list): 553 if cur not in folder: 554 folder[cur] = {"child": child_list} 555 for item in self._section_keys: 556 folder[cur][item] = 0 557 folder[cur][self.cur_section_size] = size 558 else: 559 if self.cur_section_size in folder[cur]: 560 folder[cur][self.cur_section_size] = folder[cur][self.cur_section_size] + size 561 else: 562 folder[cur][self.cur_section_size] = size 563 564 def _set_module_data(self, name, parent, cur_size): 565 if name == '': 566 return 567 if name in self.module_data: 568 if not self.module_data[name][self.cur_section_size]: 569 self.module_data[name][self.cur_section_size] = cur_size 570 else: 571 self.module_data[name][self.cur_section_size] = self.module_data[name][self.cur_section_size] + cur_size 572 elif name: 573 self.module_data[name] = { 574 'objName': name, 575 'parent': parent, 576 'romSize': 0 577 } 578 for item in self._section_keys: 579 self.module_data[name][item] = 0 580 self.module_data[name][self.cur_section_size] = cur_size 581 if self.is_rom and name: 582 self.module_data[name]['romSize'] = self.module_data[name]['romSize'] + cur_size 583 584 def _get_module_name(self, obj_name): 585 if obj_name in self._module_config and type(self._module_config[obj_name]) == str: 586 return self._module_config[obj_name] 587 else: 588 return obj_name 589 590 def _get_component_name(self, lib_name): 591 if lib_name in self._module_config and type(self._module_config[lib_name]) == str: 592 return self._module_config[lib_name] 593 else: 594 return lib_name 595 596 def _get_cur_section(self, addr): 597 self.cur_section = '' 598 self.cur_section_size = '' 599 600 for section_key in self.elf_size_data: 601 section_size = self.elf_size_data[section_key]['size'] 602 section_addr = self.elf_size_data[section_key]['addr'] 603 if section_addr <= int(addr, 16) < section_addr + section_size: 604 self.cur_section = section_key 605 self.cur_section_size = self.cur_section 606 break 607 608 self.is_rom = False 609 if self.cur_section in ('.text', '.rodata', '.data', '.l2m_gpu_text', '.plt_ramtext'): 610 self.is_rom = True 611 else: 612 for rom_part, part_size in self.rom_parts.items(): 613 if part_size['start'] <= int(addr, 16) < part_size['end']: 614 self.is_rom = True 615 break 616 617 def _reset_symbol_size_data(self): 618 length = len(self.last_symbol) 619 tmp_parent = self.last_symbol[0]['addr'] 620 all_size = int(self.size_data[tmp_parent][self.cur_section_size]) 621 622 for key, val in enumerate(self.last_symbol): 623 if key != 0: 624 tmp = val['addr'] 625 size = 0 626 if key == length - 1: 627 size = all_size 628 else: 629 size = int(self.last_symbol[key + 1]['addr'], 16) - int(self.last_symbol[key]['addr'], 16) 630 all_size = all_size - size 631 tmp_size = { 632 'objName': self.last_symbol[key]['name'], 633 'parent': self.size_data[tmp_parent]['parent'], 634 'isSymbol': True, 635 'lib': self.size_data[tmp_parent]['lib'], 636 'moduleName': self.size_data[tmp_parent]['moduleName'], 637 'componentName': self.size_data[tmp_parent]['componentName'] 638 } 639 for item in self._section_keys: 640 tmp_size[item] = 0 641 self.size_data[tmp] = tmp_size 642 self.size_data[tmp][self.cur_section_size] = size 643 644 645if __name__ == '__main__': 646 env = TargetEnvironment(sys.argv[1]) 647 chip = env.get('chip') 648 core = env.get('core') 649 bin_name = env.get('bin_name') 650 hso_xlm_chip_name = env.get('hso_xml_chip') 651 652 ELF_PATH = os.path.join(output_root, chip, core, sys.argv[1], bin_name + ".elf") 653 MAP_PATH = os.path.join(output_root, chip, core, sys.argv[1], bin_name + ".map") 654 RESULT_SAVE_PATH = os.path.join(output_root, chip, core, sys.argv[1], "image_analysis_result.html") 655 COMPILER_PATH = sys.argv[2] 656 # for debug 657 # COMPILER_PATH = os.path.join(root_dir, "tools", "bin", "compiler", "linx", "linx_170", "linx-llvm-binary-debug", 658 # "linx-llvm-binary-release-musl", "bin", "riscv32") 659 660 if hso_xlm_chip_name != None: # just for melody 661 chip = hso_xlm_chip_name 662 BUILD_CONFIG_PATH = os.path.join(root_dir, 'build', 'config', 'target_config', chip, 'image_analysis_cfg', 'module.json') 663 REMOVE_SECTIONS_CONFIG_PATH = os.path.join(root_dir, 'build', 'config', 'target_config', chip, 'image_analysis_cfg', "remove_sections.txt") 664 665 PAHT_DICT = {"elf_path": ELF_PATH, 666 "map_path": MAP_PATH, 667 "compiler_path": COMPILER_PATH, 668 "build_config_path": BUILD_CONFIG_PATH, 669 "remove_sections_config_path": REMOVE_SECTIONS_CONFIG_PATH, 670 "result_save_path": RESULT_SAVE_PATH, 671 } 672 673 IMAGE_ANALYSE_RUN = BuildDataAnalyzer(PAHT_DICT) 674 IMAGE_ANALYSE_RUN.do_build_analysis(PAHT_DICT) 675 676 print('Image Analyse Done ^_^')