Jianliang Shen | 9b4ba11 | 2022-01-19 14:57:04 +0800 | [diff] [blame^] | 1 | # ------------------------------------------------------------------------------ |
| 2 | # Copyright (c) 2022, Arm Limited. All rights reserved. |
| 3 | # |
| 4 | # SPDX-License-Identifier: BSD-3-Clause |
| 5 | # |
| 6 | # ------------------------------------------------------------------------------ |
| 7 | |
| 8 | import sqlite3 |
| 9 | import os |
| 10 | import glob |
| 11 | from xlsxwriter.workbook import Workbook |
| 12 | |
| 13 | class SQ(object): |
| 14 | """ |
| 15 | Class SQ is used to create a new sqlite3 database and search the information |
| 16 | of functions, data, sections, libraries, object files from map file. Then |
| 17 | store the result into the database for further usage. |
| 18 | |
| 19 | - Methods: |
| 20 | - SQ().update() - Create and update the database. |
| 21 | |
| 22 | - Variables: |
| 23 | - SQ().armcc - ARMCLANG option. |
| 24 | - SQ().gnuarm - GNUARM option. |
| 25 | - SQ().file_path - The map file path which detail information comes from. |
| 26 | """ |
| 27 | def __init__(self): |
| 28 | """ |
| 29 | Initialize variables. |
| 30 | """ |
| 31 | self.gnuarm = False |
| 32 | self.armcc = False |
| 33 | self.file_path = "" |
| 34 | |
| 35 | self.__gnuarm_info = [] |
| 36 | self.__sec_dict = {} |
| 37 | self.__delete() |
| 38 | self.__con = sqlite3.connect("data.db") |
| 39 | self.__cur = self.__con.cursor() |
| 40 | |
| 41 | def __delete(self): |
| 42 | """ |
| 43 | Search and delete the previous database file and excel file. |
| 44 | """ |
| 45 | for infile in glob.glob(os.path.join(os.getcwd(), '*.db')): |
| 46 | os.remove(infile) |
| 47 | for infile in glob.glob(os.path.join(os.getcwd(), '*.xlsx')): |
| 48 | os.remove(infile) |
| 49 | |
| 50 | def __new(self): |
| 51 | """ |
| 52 | Create tables in a new empty database. |
| 53 | """ |
| 54 | self.__cur.execute('''create table Summary |
| 55 | (Code INT NOT NULL, |
| 56 | RO_data INT NOT NULL, |
| 57 | RW_data INT NOT NULL, |
| 58 | ZI_data INT NOT NULL, |
| 59 | EXTRA_FLASH INT NOT NULL, |
| 60 | EXTRA_RAM INT NOT NULL, |
| 61 | Flash INT NOT NULL, |
| 62 | RAM INT NOT NULL);''') |
| 63 | self.__cur.execute('''create table Section |
| 64 | (name TEXT NOT NULL, |
| 65 | size INT NOT NULL, |
| 66 | address TEXT NOT NULL, |
| 67 | pad_size INT NOT NULL);''') |
| 68 | self.__cur.execute('''create table Function |
| 69 | (name TEXT NOT NULL, |
| 70 | section TEXT NOT NULL, |
| 71 | size INT NOT NULL, |
| 72 | base_addr TEXT NOT NULL, |
| 73 | obj_file TEXT NOT_NULL, |
| 74 | lib_file TEXT NOT_NULL);''') |
| 75 | self.__cur.execute('''create table Data |
| 76 | (name TEXT NOT NULL, |
| 77 | section TEXT NOT NULL, |
| 78 | size INT NOT NULL, |
| 79 | base_addr TEXT NOT NULL, |
| 80 | type TEXT NOT NULL, |
| 81 | obj_file TEXT NOT_NULL, |
| 82 | lib_file TEXT NOT_NULL);''') |
| 83 | self.__cur.execute('''create table Library |
| 84 | (name TEXT NOT NULL, |
| 85 | flashsize INT NOT NULL, |
| 86 | ramsize INT NOT NULL, |
| 87 | code INT NOT NULL, |
| 88 | rodata INT NOT NULL, |
| 89 | rwdata INT NOT NULL, |
| 90 | zidata INT NOT NULL, |
| 91 | incdata INT NOT_NULL, |
| 92 | Debug INT NOT NULL);''') |
| 93 | self.__cur.execute('''create table Object |
| 94 | (name TEXT NOT NULL, |
| 95 | library TEXT NOT NULL, |
| 96 | flashsize INT NOT NULL, |
| 97 | ramsize INT NOT NULL, |
| 98 | code INT NOT NULL, |
| 99 | rodata INT NOT NULL, |
| 100 | rwdata INT NOT NULL, |
| 101 | zidata INT NOT NULL, |
| 102 | incdata INT NOT_NULL, |
| 103 | Debug INT NOT NULL);''') |
| 104 | if self.gnuarm: |
| 105 | self.__cur.execute('''create table Unknown |
| 106 | (name TEXT NOT NULL, |
| 107 | section TEXT NOT NULL, |
| 108 | size INT NOT NULL, |
| 109 | base_addr TEXT NOT NULL, |
| 110 | type TEXT NOT NULL, |
| 111 | obj_file TEXT NOT_NULL, |
| 112 | lib_file TEXT NOT_NULL);''') |
| 113 | |
| 114 | def __collect_summary(self): |
| 115 | code_size = ro_data = rw_data = zi_data = flash_size = ram_size = extra_ram = extra_flash = 0 |
| 116 | if self.gnuarm: |
| 117 | max_ram_addr = max_flash_addr = max_addr_ram_sym_size = max_addr_flash_sym_size = 0 |
| 118 | flash_start_addr, x, ram_start_addr, y = self.__get_ram_and_flash_start_addr() |
| 119 | for s in self.__gnuarm_info: |
| 120 | if s[3] == "text": |
| 121 | code_size += s[1] |
| 122 | if s[3] == "rodata": |
| 123 | ro_data += s[1] |
| 124 | if s[3] == "data": |
| 125 | rw_data += s[1] |
| 126 | if s[3] == "bss": |
| 127 | zi_data += s[1] |
| 128 | if s[3] == "unknown_ram": |
| 129 | extra_ram += s[1] |
| 130 | if s[3] == "unknown_flash": |
| 131 | extra_flash += s[1] |
| 132 | |
| 133 | for s in self.__sec_dict.keys(): |
| 134 | if self.__sec_dict[s]['type'] == 'ram': |
| 135 | max_ram_addr = max(max_ram_addr, int(self.__sec_dict[s]['addr'], 16)) |
| 136 | max_addr_ram_sym_size = self.__sec_dict[s]['size'] |
| 137 | ram_size = max_ram_addr - ram_start_addr + max_addr_ram_sym_size |
| 138 | |
| 139 | """ |
| 140 | Some special sections like 'psp_stack' or 'heap' are pre-allocated, |
| 141 | and filled with zero. They are belonging to bss/ZI part. |
| 142 | """ |
| 143 | if self.__sec_dict[s]['size'] == self.__sec_dict[s]['fill']: |
| 144 | zi_data += self.__sec_dict[s]['size'] |
| 145 | if self.__sec_dict[s]['type'] == 'flash': |
| 146 | max_flash_addr = max(max_flash_addr, int(self.__sec_dict[s]['addr'], 16)) |
| 147 | max_addr_flash_sym_size = self.__sec_dict[s]['size'] |
| 148 | flash_size = max_flash_addr - flash_start_addr + max_addr_flash_sym_size |
| 149 | |
| 150 | """ |
| 151 | For Secure image, the TFM_DATA part is loaded from Flash. |
| 152 | """ |
| 153 | for line in open(self.file_path, "r"): |
| 154 | if line.find("load address") >= 0: |
| 155 | extra_flash_addr = int(line.split()[-1] ,16) |
| 156 | extra_flash_data = int(line.split()[-4], 16) |
| 157 | if extra_flash_addr == max_flash_addr + max_addr_flash_sym_size: |
| 158 | flash_size += extra_flash_data |
| 159 | |
| 160 | elif self.armcc: |
| 161 | for line in open(self.file_path, "r"): |
| 162 | if line.find("gram Size: Code=") > 0: |
| 163 | content = line.split() |
| 164 | code_size = int(content[2].split('=')[1]) |
| 165 | ro_data = int(content[3].split('=')[1]) |
| 166 | rw_data = int(content[4].split('=')[1]) |
| 167 | zi_data = int(content[5].split('=')[1]) |
| 168 | flash_size = code_size + ro_data + rw_data |
| 169 | ram_size = rw_data + zi_data |
| 170 | |
| 171 | self.__cur.execute("insert into Summary values (?,?,?,?,?,?,?,?)", |
| 172 | (code_size, |
| 173 | ro_data, |
| 174 | rw_data, |
| 175 | zi_data, |
| 176 | extra_flash, |
| 177 | extra_ram, |
| 178 | flash_size, |
| 179 | ram_size)) |
| 180 | |
| 181 | def __collect_section(self): |
| 182 | if self.gnuarm: |
| 183 | for s in self.__gnuarm_info: |
| 184 | if s[3] == "text": |
| 185 | self.__cur.execute("insert into Function values (?,?,?,?,?,?)", |
| 186 | (s[0], s[6], s[1], s[2], s[4], s[5])) |
| 187 | elif s[3] == "rodata": |
| 188 | self.__cur.execute("insert into Data values (?,?,?,?,?,?,?)", |
| 189 | (s[0], s[6], s[1], s[2], "RO", s[4], s[5])) |
| 190 | elif s[3] == "data": |
| 191 | self.__cur.execute("insert into Data values (?,?,?,?,?,?,?)", |
| 192 | (s[0], s[6], s[1], s[2], "RW", s[4], s[5])) |
| 193 | elif s[3] == "bss": |
| 194 | self.__cur.execute("insert into Data values (?,?,?,?,?,?,?)", |
| 195 | (s[0], s[6], s[1], s[2], "ZI", s[4], s[5])) |
| 196 | else: |
| 197 | self.__cur.execute("insert into Unknown values (?,?,?,?,?,?,?)", |
| 198 | (s[0], s[6], s[1], s[2], s[3], s[4], s[5])) |
| 199 | for s in self.__sec_dict.keys(): |
| 200 | self.__cur.execute("insert into Section values (?,?,?,?)", |
| 201 | (self.__sec_dict[s]['name'], |
| 202 | self.__sec_dict[s]['size'], |
| 203 | self.__sec_dict[s]['addr'], |
| 204 | self.__sec_dict[s]['fill'])) |
| 205 | elif self.armcc: |
| 206 | line_idx, line_start = 0, 0 |
| 207 | section_name = "" |
| 208 | section_addr = "" |
| 209 | section_size = 0 |
| 210 | section_pad_size = 0 |
| 211 | for line in open(self.file_path, "r"): |
| 212 | line_idx += 1 |
| 213 | |
| 214 | if line.find("Execution Region") > 0: |
| 215 | if len(section_name) > 0: |
| 216 | self.__cur.execute("insert into Section values (?,?,?,?)", |
| 217 | (section_name, |
| 218 | section_size, |
| 219 | section_addr, |
| 220 | section_pad_size)) |
| 221 | line_start = line_idx + 1 |
| 222 | |
| 223 | content = line.split() |
| 224 | if len(content) >= 10: |
| 225 | section_name = content[2] |
| 226 | section_addr = content[4][:-1] |
| 227 | section_size = int(content[6][:-1], 16) |
| 228 | section_pad_size = 0 |
| 229 | if line.find("PAD\n") > 0 and line_idx > line_start and line_start > 0: |
| 230 | section_pad_size += int(line.split()[1], 16) |
| 231 | if line.find(" Code ") > 0: |
| 232 | content = line.split() |
| 233 | if len(content) >= 7: |
| 234 | if line.find(" * ") > 0: |
| 235 | content.remove("*") |
| 236 | func_name = content[5].strip().split('.')[-1] |
| 237 | if content[6].find('(') > 0: |
| 238 | object_file = content[6][content[6].find('(') + 1: -1] |
| 239 | lib_file = content[6][:content[6].find('(')] |
| 240 | else: |
| 241 | object_file = lib_file = content[6] |
| 242 | self.__cur.execute("insert into Function values (?,?,?,?,?,?)", |
| 243 | (func_name, |
| 244 | section_name, |
| 245 | int(content[1].strip(), 16), |
| 246 | content[0].strip(), |
| 247 | object_file, |
| 248 | lib_file)) |
| 249 | if line.find(" Data ") > 0 or line.find(" Zero ") > 0: |
| 250 | content = line.split() |
| 251 | if len(content) == 7: |
| 252 | if content[2] == "Zero": |
| 253 | data_type = "ZI" |
| 254 | else: |
| 255 | data_type = content[3] |
| 256 | data_name = content[5].strip() |
| 257 | if content[6].find('(') > 0: |
| 258 | object_file = content[6][content[6].find('(') + 1: -1] |
| 259 | lib_file = content[6][:content[6].find('(')] |
| 260 | else: |
| 261 | object_file = lib_file = content[6] |
| 262 | self.__cur.execute("insert into Data values (?,?,?,?,?,?,?)", |
| 263 | (data_name, |
| 264 | section_name, |
| 265 | int(content[1].strip(), 16), |
| 266 | content[0].strip(), |
| 267 | data_type, |
| 268 | object_file, |
| 269 | lib_file)) |
| 270 | |
| 271 | def __collect_library(self): |
| 272 | if self.gnuarm: |
| 273 | lib_detail_list = self.__collect_set(5) |
| 274 | for s in lib_detail_list: |
| 275 | self.__cur.execute("insert into Library values (?,?,?,?,?,?,?,?,?)", |
| 276 | (s['name'], |
| 277 | s['Code']+ s['RO'] + s['RW'], |
| 278 | s['RW'] + s['ZI'], |
| 279 | s['Code'], |
| 280 | s['RO'], |
| 281 | s['RW'], |
| 282 | s['ZI'], |
| 283 | 0, 0)) |
| 284 | |
| 285 | elif self.armcc: |
| 286 | line_idx, line_start = 0, 0 |
| 287 | for line in open(self.file_path, "r"): |
| 288 | line_idx += 1 |
| 289 | if line.find("Code (inc. data) RO Data RW Data ZI Data Debug Library Name") > 0: |
| 290 | line_start = line_idx + 1 |
| 291 | if line_idx > line_start and line_start > 0: |
| 292 | content = line.split() |
| 293 | if len(content) == 7: |
| 294 | self.__cur.execute("insert into Library values (?,?,?,?,?,?,?,?,?)", |
| 295 | (content[6], |
| 296 | int(content[0]) + int(content[2]) + int(content[3]), |
| 297 | int(content[3]) + int(content[4]), |
| 298 | content[0], |
| 299 | content[2], |
| 300 | content[3], |
| 301 | content[4], |
| 302 | content[1], |
| 303 | content[5])) |
| 304 | else: |
| 305 | break |
| 306 | |
| 307 | def __collect_obj(self): |
| 308 | if self.gnuarm: |
| 309 | obj_lib = "" |
| 310 | obj_detail_list = self.__collect_set(4) |
| 311 | for s in obj_detail_list: |
| 312 | for t in self.__gnuarm_info: |
| 313 | if t[4] == s['name']: |
| 314 | obj_lib = t[5] |
| 315 | break |
| 316 | self.__cur.execute("insert into Object values (?,?,?,?,?,?,?,?,?,?)", |
| 317 | (s['name'], |
| 318 | obj_lib, |
| 319 | s['Code']+ s['RO'] + s['RW'], |
| 320 | s['RW'] + s['ZI'], |
| 321 | s['Code'], |
| 322 | s['RO'], |
| 323 | s['RW'], |
| 324 | s['ZI'], |
| 325 | 0, 0)) |
| 326 | elif self.armcc: |
| 327 | line_idx, line_start = 0, 0 |
| 328 | for line in open(self.file_path, "r"): |
| 329 | line_idx += 1 |
| 330 | if line.find("Code (inc. data) RO Data RW Data ZI Data Debug Object Name") > 0: |
| 331 | line_start = line_idx + 1 |
| 332 | if line_idx > line_start and line_start > 0: |
| 333 | content = line.split() |
| 334 | if len(content) == 7: |
| 335 | self.__cur.execute("insert into Object values (?,?,?,?,?,?,?,?,?,?)", |
| 336 | (content[6], |
| 337 | "no library", |
| 338 | int(content[0]) + int(content[2]) + int(content[3]), |
| 339 | int(content[3]) + int(content[4]), |
| 340 | content[0], |
| 341 | content[2], |
| 342 | content[3], |
| 343 | content[4], |
| 344 | content[1], |
| 345 | content[5])) |
| 346 | else: |
| 347 | break |
| 348 | line_idx, line_start = 0, 0 |
| 349 | for line in open(self.file_path, "r"): |
| 350 | line_idx += 1 |
| 351 | if line.find("Code (inc. data) RO Data RW Data ZI Data Debug Library Member Name") > 0: |
| 352 | line_start = line_idx + 1 |
| 353 | if line_idx > line_start and line_start > 0: |
| 354 | content = line.split() |
| 355 | if len(content) == 7: |
| 356 | obj_name = content[6] |
| 357 | library_file = "" |
| 358 | for line in open(self.file_path, "r"): |
| 359 | if line.find(obj_name) > 0: |
| 360 | ch_r = line[line.find(obj_name) + len(obj_name)] |
| 361 | ch_l = line[line.find(obj_name) - 1] |
| 362 | if ch_l == '(' and ch_r == ')': |
| 363 | library_file = line.split()[6][:line.split()[6].find('(')] |
| 364 | if len(library_file) == 0: |
| 365 | library_file = "no library" |
| 366 | self.__cur.execute("insert into Object values (?,?,?,?,?,?,?,?,?,?)", |
| 367 | (content[6], |
| 368 | library_file, |
| 369 | int(content[0]) + int(content[2]) + int(content[3]), |
| 370 | int(content[3]) + int(content[4]), |
| 371 | content[0], |
| 372 | content[2], |
| 373 | content[3], |
| 374 | content[4], |
| 375 | content[1], |
| 376 | content[5])) |
| 377 | else: |
| 378 | break |
| 379 | |
| 380 | def __get_ram_and_flash_start_addr(self): |
| 381 | start = False |
| 382 | for line in open(self.file_path, "r"): |
| 383 | if line.find('Memory Configuration') >= 0: |
| 384 | start = True |
| 385 | if line.find('Linker script and memory map') == 0: |
| 386 | break |
| 387 | if start: |
| 388 | if line.find('FLASH') >= 0: |
| 389 | flash_start_addr = int(line.split()[1].strip(), 16) |
| 390 | flash_end_addr = int(line.split()[1].strip(), 16) + int(line.split()[2].strip(), 16) |
| 391 | if line.find('RAM') >= 0: |
| 392 | ram_start_addr = int(line.split()[1].strip(), 16) |
| 393 | ram_end_addr = int(line.split()[1].strip(), 16) + int(line.split()[2].strip(), 16) |
| 394 | return flash_start_addr, flash_end_addr, ram_start_addr, ram_end_addr |
| 395 | |
| 396 | def __get_info_from_gnuarm_map(self): |
| 397 | def get_key_content(): |
| 398 | start, end, real_start = False, False, False |
| 399 | content = "" |
| 400 | for line in open(self.file_path, "r"): |
| 401 | if line.find('Linker script and memory map') >= 0: |
| 402 | start = True |
| 403 | if line.find('OUTPUT(') == 0: |
| 404 | end = True |
| 405 | if start and not real_start: |
| 406 | if(line[0] == '.'): |
| 407 | real_start = True |
| 408 | if real_start and not end: |
| 409 | content += line |
| 410 | return content.split('\n')[:-2] |
| 411 | |
| 412 | def output_to_gnuarm_info(): |
| 413 | type_founded = False |
| 414 | info = [cur_sym_name, cur_sym_size, cur_sym_addr, "type", obj, lib, cur_sec_name] |
| 415 | for type in ["text", "data", "bss", "rodata"]: |
| 416 | info[3] = type |
| 417 | if cur_sym_name.find('.' + type) == 0: |
| 418 | if cur_sym_name.find('.' + type + '.') == 0: |
| 419 | info[0] = cur_sym_name[len(type)+2:] |
| 420 | self.__gnuarm_info.append(info) |
| 421 | type_founded = True |
| 422 | break |
| 423 | self.__gnuarm_info.append(info) |
| 424 | type_founded = True |
| 425 | if not type_founded: |
| 426 | if int(cur_sym_addr,16) >= flash_start_addr and int(cur_sym_addr,16) <= flash_end_addr: |
| 427 | info[3] = "unknown_flash" |
| 428 | self.__gnuarm_info.append(info) |
| 429 | if int(cur_sym_addr,16) >= ram_start_addr and int(cur_sym_addr,16) <= ram_end_addr: |
| 430 | info[3] = "unknown_ram" |
| 431 | self.__gnuarm_info.append(info) |
| 432 | |
| 433 | def get_obj_and_lib(line): |
| 434 | lib = line[line.rfind('/') + 1:line.rfind('.o') + 2] |
| 435 | obj = lib[lib.find("(") + 1:lib.rfind('.o')] + '.o' |
| 436 | if lib.find('(') > 0: |
| 437 | lib = lib[:lib.find("(")] |
| 438 | else: |
| 439 | lib = "no library" |
| 440 | return lib, obj |
| 441 | |
| 442 | def get_part_list(idx): |
| 443 | ret = [] |
| 444 | while len(lines[idx]) > 0 and lines[idx].split()[0].find('0x0000') >= 0: |
| 445 | if len(lines[idx].split()) == 2: |
| 446 | cur_addr = lines[idx].split()[0].strip() |
| 447 | cur_name = lines[idx].split()[1].strip() |
| 448 | if cur_sym_name.find(cur_name) >= 0: |
| 449 | break |
| 450 | else: |
| 451 | delta = -1 |
| 452 | cur_idx = idx + 1 |
| 453 | next_addr = '' |
| 454 | while len(lines[cur_idx]) >= 0: |
| 455 | if lines[cur_idx].find('0x0000') >= 0: |
| 456 | for s in lines[cur_idx].split(): |
| 457 | if s.find('0x0000') >= 0: |
| 458 | next_addr = s.strip() |
| 459 | delta = int(next_addr, 16) - int(cur_addr, 16) |
| 460 | if delta >= 0: |
| 461 | break |
| 462 | cur_idx += 1 |
| 463 | ret.append(['0x' + cur_addr[-8:], cur_sym_name+'.'+cur_name, delta]) |
| 464 | else: |
| 465 | break |
| 466 | idx += 1 |
| 467 | return ret |
| 468 | |
| 469 | lines = get_key_content() |
| 470 | i_max = len(lines) |
| 471 | part_list = [] |
| 472 | cur_sym_name, cur_sym_addr, cur_sym_size, lib, obj = "", "", "", "", "" |
| 473 | flash_start_addr , flash_end_addr , ram_start_addr , ram_end_addr = self.__get_ram_and_flash_start_addr() |
| 474 | for i in range(i_max): |
| 475 | lib, obj = "no_library", "no_object" |
| 476 | if len(lines[i]) > 0 and lines[i][0] == '.': |
| 477 | cur_sec_name = lines[i].split()[0][1:] |
| 478 | if len(lines[i].split()) > 1: |
| 479 | cur_sec_addr = lines[i].split()[1] |
| 480 | cur_sec_size = lines[i].split()[2] |
| 481 | else: |
| 482 | cur_sec_addr = lines[i+1].split()[0] |
| 483 | cur_sec_size = lines[i+1].split()[1] |
| 484 | if cur_sec_addr.find('0x00') < 0: |
| 485 | continue |
| 486 | if int(cur_sec_addr,16) >= flash_start_addr and int(cur_sec_addr,16) <= flash_end_addr: |
| 487 | self.__sec_dict[cur_sec_name] = {'name': cur_sec_name, |
| 488 | 'addr': '0x' + cur_sec_addr[-8:], |
| 489 | 'fill': 0, |
| 490 | 'size': int(cur_sec_size, 16), |
| 491 | 'type': 'flash'} |
| 492 | if int(cur_sec_addr,16) >= ram_start_addr and int(cur_sec_addr,16) <= ram_end_addr: |
| 493 | self.__sec_dict[cur_sec_name] = {'name': cur_sec_name, |
| 494 | 'addr': '0x' + cur_sec_addr[-8:], |
| 495 | 'fill': 0, |
| 496 | 'size': int(cur_sec_size, 16), |
| 497 | 'type': 'ram'} |
| 498 | |
| 499 | if len(lines[i]) > 0 and lines[i][0] == ' ' and lines[i][1] != ' ': |
| 500 | cur_sym_name = lines[i].split()[0].strip() |
| 501 | if len(lines[i].split()) > 2: |
| 502 | cur_sym_addr = lines[i].split()[1].strip() |
| 503 | cur_sym_size = lines[i].split()[2].strip() |
| 504 | if cur_sym_addr.find('0x00') == 0 and cur_sym_size.find('0x') == 0: |
| 505 | cur_sym_addr = '0x' + cur_sym_addr[-8:] |
| 506 | cur_sym_size = int(cur_sym_size, 16) |
| 507 | if lines[i].find('/') > 0: |
| 508 | lib, obj = get_obj_and_lib(lines[i]) |
| 509 | part_list = get_part_list(i+1) |
| 510 | else: |
| 511 | continue |
| 512 | |
| 513 | elif len(lines[i+1]) > 0 and lines[i+1].split()[0].find('0x00') >= 0: |
| 514 | cur_sym_addr = lines[i+1].split()[0].strip() |
| 515 | cur_sym_size = lines[i+1].split()[1].strip() |
| 516 | if cur_sym_addr.find('0x00') == 0 and cur_sym_size.find('0x') == 0: |
| 517 | cur_sym_addr = '0x' + cur_sym_addr[-8:] |
| 518 | cur_sym_size = int(cur_sym_size, 16) |
| 519 | if lines[i+1].find('/') > 0: |
| 520 | lib, obj = get_obj_and_lib(lines[i+1]) |
| 521 | part_list = get_part_list(i+2) |
| 522 | else: |
| 523 | continue |
| 524 | else: |
| 525 | continue |
| 526 | |
| 527 | if cur_sym_name.find("*fill*") >= 0: |
| 528 | self.__sec_dict[cur_sec_name]['fill'] += cur_sym_size |
| 529 | continue |
| 530 | |
| 531 | if len(part_list) > 0: |
| 532 | for s in part_list: |
| 533 | cur_sym_addr = s[0] |
| 534 | cur_sym_name = s[1] |
| 535 | cur_sym_size = s[2] |
| 536 | output_to_gnuarm_info() |
| 537 | else: |
| 538 | output_to_gnuarm_info() |
| 539 | |
| 540 | def __output_to_excel(self): |
| 541 | def transform_db_2_excel(table_name): |
| 542 | worksheet = workbook.add_worksheet(name=table_name) |
| 543 | cursor = self.__cur.execute('select * from {}'.format(table_name)) |
| 544 | names = list(map(lambda x: x[0], cursor.description)) |
| 545 | len_list = [] |
| 546 | for s in names: |
| 547 | len_list.append(max(15, len(s))) |
| 548 | for i in range(len(names)): |
| 549 | worksheet.write(0, i, names[i], title_m) |
| 550 | |
| 551 | mysel = self.__cur.execute('select * from {}'.format(table_name)) |
| 552 | for i, row in enumerate(mysel): |
| 553 | for j, value in enumerate(row): |
| 554 | len_list[j] = max(len_list[j], len(str(value))) |
| 555 | worksheet.write(i + 1, j, value, page_m) |
| 556 | worksheet.set_column(j, j, width=len_list[j]) |
| 557 | |
| 558 | table_list = ["Summary", "Section", "Library", "Object", "Function", "Data"] |
| 559 | if self.gnuarm: |
| 560 | table_list.append("Unknown") |
| 561 | workbook = Workbook('data.xlsx') |
| 562 | title_m = workbook.add_format({'bold': True, |
| 563 | 'align': 'left', |
| 564 | 'font_size': 12}) |
| 565 | page_m = workbook.add_format({'align': 'left', |
| 566 | 'font_size': 10}) |
| 567 | for table in table_list: |
| 568 | transform_db_2_excel(table) |
| 569 | workbook.close() |
| 570 | |
| 571 | def __collect_set(self, index): |
| 572 | name_list = [] |
| 573 | detail_list = [] |
| 574 | for s in self.__gnuarm_info: |
| 575 | if s[index] not in name_list: |
| 576 | name_list.append(s[index]) |
| 577 | if s[3] == "text": |
| 578 | detail_list.append({'name': s[index], 'Code':s[1],'ZI':0, 'RO':0,'RW':0}) |
| 579 | if s[3] == "rodata": |
| 580 | detail_list.append({'name': s[index], 'Code':0,'ZI':0, 'RO':s[1],'RW':0}) |
| 581 | if s[3] == "data": |
| 582 | detail_list.append({'name': s[index], 'Code':0,'ZI':0, 'RO':0,'RW':s[1]}) |
| 583 | if s[3] == "bss": |
| 584 | detail_list.append({'name': s[index], 'Code':0,'ZI':s[1], 'RO':0,'RW':0}) |
| 585 | else: |
| 586 | for t in detail_list: |
| 587 | if t['name'] == s[index]: |
| 588 | if s[3] == "text": |
| 589 | t['Code'] += s[1] |
| 590 | if s[3] == "rodata": |
| 591 | t['RO'] += s[1] |
| 592 | if s[3] == "data": |
| 593 | t['RW'] += s[1] |
| 594 | if s[3] == "bss": |
| 595 | t['ZI'] += s[1] |
| 596 | return detail_list |
| 597 | |
| 598 | def update(self): |
| 599 | """ |
| 600 | Create the database and collect information from map file, then store |
| 601 | it into the database, and write to excel file for further usage. |
| 602 | """ |
| 603 | self.__new() |
| 604 | if self.gnuarm: |
| 605 | self.__get_info_from_gnuarm_map() |
| 606 | self.__collect_summary() |
| 607 | self.__collect_section() |
| 608 | self.__collect_library() |
| 609 | self.__collect_obj() |
| 610 | self.__con.commit() |
| 611 | self.__output_to_excel() |
| 612 | self.__con.close() |