1#!/usr/bin/env python 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 sys,string,re,os 17from ctypes import * 18from parse_basic import * 19from xml_main import * 20import json 21 22g_drwaf_all_tag_tup = ('DW_TAG_compile_unit', 23 'DW_TAG_subprogram', 24 'DW_TAG_variable', 25 'DW_TAG_GNU_call_site', 26 'DW_TAG_typedef', 27 'DW_TAG_base_type', 28 'DW_TAG_array_type', 29 'DW_TAG_subrange_type', 30 'DW_TAG_pointer_type', 31 'DW_TAG_subroutine_type', 32 'DW_TAG_formal_parameter', 33 'DW_TAG_const_type', 34 'DW_TAG_structure_type', 35 'DW_TAG_member', 36 'DW_TAG_enumeration_type', 37 'DW_TAG_enumerator', 38 'DW_TAG_unspecified_parameters', 39 'DW_TAG_lexical_block', 40 'DW_TAG_inlined_subroutine', 41 'DW_TAG_union_type', 42 'DW_TAG_volatile_type', 43 'DW_TAG_label', 44 'DW_TAG_restrict_type', 45 'DW_TAG_namespace', 46 'DW_TAG_class_type', 47 'DW_TAG_template_type_param', 48 'DW_TAG_inheritance', 49 'DW_TAG_GNU_template_parameter_pack', 50 'DW_TAG_template_value_param', 51 'DW_TAG_imported_declaration', 52 'DW_TAG_reference_type', 53 'DW_TAG_rvalue_reference_type', 54 'DW_TAG_unspecified_type', 55 'DW_TAG_imported_module', 56 'DW_TAG_GNU_call_site_parameter') 57 58g_drwaf_all_attr_tup = ('DW_AT_producer', 59 'DW_AT_language', 60 'DW_AT_name', 61 'DW_AT_stmt_list', 62 'DW_AT_comp_dir', 63 'DW_AT_low_pc', 64 'DW_AT_ranges', 65 'DW_AT_high_pc', 66 'DW_AT_frame_base', 67 'DW_AT_GNU_all_call_sites', 68 'DW_AT_decl_file', 69 'DW_AT_decl_line', 70 'DW_AT_prototyped', 71 'DW_AT_type', 72 'DW_AT_external', 73 'DW_AT_location', 74 'DW_AT_abstract_origin', 75 'DW_AT_GNU_tail_call', 76 'DW_AT_encoding', 77 'DW_AT_byte_size', 78 'DW_AT_count', 79 'DW_AT_data_member_location', 80 'DW_AT_const_value', 81 'DW_AT_declaration', 82 'DW_AT_inline', 83 'DW_AT_call_file', 84 'DW_AT_call_line', 85 'DW_AT_call_column', 86 'DW_AT_GNU_call_site_target', 87 'DW_AT_bit_size', 88 'DW_AT_bit_offset', 89 'DW_AT_alignment', 90 'DW_AT_sibling', 91 'DW_AT_upper_bound', 92 'DW_AT_entry_pc', 93 'DW_AT_GNU_all_tail_call_sites', 94 'DW_AT_specification', 95 'DW_AT_linkage_name', 96 'DW_AT_calling_convention', 97 'DW_AT_accessibility', 98 'DW_AT_artificial', 99 'DW_AT_explicit', 100 'DW_AT_containing_type', 101 'DW_AT_virtuality', 102 'DW_AT_vtable_elem_location', 103 'DW_AT_noreturn', 104 'DW_AT_object_pointer', 105 'DW_AT_export_symbols', 106 'DW_AT_enum_class', 107 'DW_AT_GNU_call_site_value', 108 'DW_AT_import') 109 110 111class TreeNode: 112 def __init__(self): 113 self.data = None 114 self.son = [] 115 self.parent = None 116 117class Tag: 118 def __init__(self): 119 self.level_str=None 120 self.entry_str=None 121 self.type_str = None 122 self.at_list = {} 123 self.level = None 124 self.son_tag_list = [] 125 self.parent = None 126 self.at_name = None 127 self.op_addr = None 128 self.byte_size = None 129 self.member_location = None 130 self.random_name = None 131 self.c_type_name = None 132 self.member_name = None 133 self.c_type_root_name = None 134 self.member_array_tag = None 135 self.member_type_tag = None 136 self.member_bit_size = None 137 self.root_tag = None 138 self.var_array = [] 139 self.symbol_location = None 140 141class Attribute: 142 def __init__(self): 143 self.entry_str=None 144 self.type_str=None 145 self.val_attr = None 146 147class Signature: 148 def __init__(self): 149 self.signature=None 150 self.sign_entry=0 151 152class ParseCtrl(): 153 def __init__(self): 154 self.debug_type = None 155 self.symbol_dic_init=False 156 self.parse_debug_info_phase_0=False 157 self.parse_debug_info_phase_1=False 158 self.out_type = 'python' 159 self.symbol_dic={} 160 self.tag_list = [] 161 self.tag_dic_by_entry = {} 162 self.sign_list = [] 163 self.sign_entry_by_id = {} 164 self.last_tag = [None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None, 165 None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None,None]#支持48个等级 166 self.tag_name_dic = {} 167 self.attr_name_dic = {} 168 self.random_val = 0 169 self.class_fd = None 170 self.out_type_dic={} 171 self.var_symbol_dic={} 172 self.c_basic_type=[ 173 'char','int','unsigned char','bool' 174 ] 175 176 self.name_convert_dic = { 177 'bool':'td_bool', 178 'char':'td_char', 179 'signed char':'td_char', 180 'unsigned char':'td_uchar', 181 'int':'td_s32', 182 'unsigned int':'td_u32', 183 'short':'td_s16', 184 'unsigned short':'td_u16', 185 'short unsigned int':'td_u16', 186 'long':'td_s32', 187 'unsigned long':'td_u32', 188 'long long':'td_s64', 189 'unsigned long long':'td_u64', 190 'float':'td_float', 191 'double':'td_double', 192 '__ARRAY_SIZE_TYPE__':'td_u32', 193 'long unsigned int':'td_u32', 194 '_Bool':'td_bool', 195 } 196 197 for key in self.name_convert_dic: 198 self.out_type_dic[self.name_convert_dic[key]]=True 199 200 def print_root_basic_type(self,fp): 201 if self.out_type=='python': 202 print('from ctypes import *',file=self.class_fd) 203 print('td_bool=c_bool',file=fp) 204 print('td_char=c_char',file=fp) 205 print('td_uchar=c_ubyte',file=fp) 206 print('td_s16=c_short',file=fp) 207 print('td_u16=c_ushort',file=fp) 208 print('td_s32=c_int',file=fp) 209 print('td_u32=c_uint',file=fp) 210 print('td_s64=c_longlong',file=fp) 211 print('td_u64=c_ulonglong',file=fp) 212 print('td_float=c_float',file=fp) 213 print('td_double=c_double',file=fp) 214 elif self.out_type=='c': 215 print('typedef unsigned char td_bool;',file=fp) 216 print('typedef char td_char;',file=fp) 217 print('typedef unsigned char td_uchar;',file=fp) 218 print('typedef short td_s16;',file=fp) 219 print('typedef unsigned short td_u16;',file=fp) 220 print('typedef short unsigned int td_u16;',file=fp) #add for arm, UINT16 is short unsiged int 221 print('typedef int td_s32;',file=fp) 222 print('typedef unsigned int td_u32;',file=fp) 223 print('typedef long long td_s64;',file=fp) 224 print('typedef unsigned long long td_u64;',file=fp) 225 print('typedef float td_float;',file=fp) 226 print('typedef double td_double;',file=fp) 227 self.out_type_dic['td_bool']=True 228 self.out_type_dic['td_char']=True 229 self.out_type_dic['td_uchar']=True 230 self.out_type_dic['td_s16']=True 231 self.out_type_dic['td_u16']=True 232 self.out_type_dic['td_s32']=True 233 self.out_type_dic['td_u32']=True 234 self.out_type_dic['td_s64']=True 235 self.out_type_dic['td_u64']=True 236 self.out_type_dic['td_float']=True 237 self.out_type_dic['td_double']=True 238 239 240 def append_space(self,line,cnt): 241 i=0 242 while i<cnt: 243 line=' '+line 244 i=i+1 245 return line 246 247 def conver_base_name(self,name):#将基础类型转为ctypes类型 248 if name==None: 249 return None 250 if name in self.name_convert_dic: 251 return self.name_convert_dic[name] 252 return None 253 254 def create_random_name(self):#生成一个随机名称 255 self.random_val = self.random_val+1 256 return "random_type_%d"%(self.random_val) 257 258 def create_random_var_name(self):#生成一个随机名称 259 self.random_val = self.random_val+1 260 return "random_var_%d"%(self.random_val) 261 262 def stat_add_tag_type(self,tag):#统计量 263 self.tag_name_dic[tag.type_str] = tag.type_str 264 265 def stat_add_attr_type(self,attr):#统计量 266 self.attr_name_dic[attr.type_str] = attr.type_str 267 268 def print_tag_info(self,tag,level):#打印tag 269 suojin='' 270 i=0 271 while i<level: 272 suojin="%s%s"%(suojin,'\t') 273 i=i+1 274 275 #print("%s[tag]type=%s(%s) level=%d,entry=%s,"%(suojin,tag.type_str,tag.at_name,tag.level,tag.entry_str)) 276 if tag.at_list != None: 277 for key in tag.at_list: 278 attr = tag.at_list[key] 279 print('[attr]entry=%s,type=%s,val=%s'%(attr.entry_str,attr.type_str,attr.val_attr)) 280 if tag.at_name != None: 281 print("%sat_name=%s"%(suojin,tag.at_name)) 282 if tag.random_name != None: 283 print("%srandom_name=%s"%(suojin,tag.random_name)) 284 if tag.byte_size != None: 285 print("%sbyte_size=%d"%(suojin,tag.byte_size)) 286 if tag.op_addr != None: 287 print("%saddr=%d"%(suojin,tag.op_addr)) 288 if tag.member_location != None: 289 print("%soffset=%s"%(suojin,tag.member_location)) 290 if tag.c_type_name != None: 291 print("%sc_type_name=%s"%(suojin,tag.c_type_name)) 292 if tag.c_type_root_name != None: 293 print("%sc_type_root_name=%s"%(suojin,tag.c_type_root_name)) 294 295 if len(tag.var_array) != 0: 296 print("%svar_array=%s"%(suojin,tag.var_array)) 297 298 if tag.type_str == 'DW_TAG_member': 299 self.print_tag_info(tag.member_type_tag,level+1) 300 if(tag.member_array_tag): 301 self.print_tag_info(tag.member_array_tag,level+1) 302 303 if(level==0): 304 print('') 305 print('') 306 #input("print_tag") 307 308 def append_tag(self,tag): 309 if tag: 310 self.tag_list.append(tag) 311 self.tag_dic_by_entry[tag.entry_str]=tag 312 if tag.level!=0: 313 self.last_tag[tag.level-1].son_tag_list.append(tag) 314 tag.parent = self.last_tag[tag.level-1] 315 self.last_tag[tag.level]=tag 316 #self.print_tag_info(tag,0) 317 318 def get_tag_by_entry_name(self,entry_str):#通过入口名查找tag 319 if entry_str==None: 320 return None 321 if entry_str not in self.tag_dic_by_entry: 322 return None 323 return self.tag_dic_by_entry[entry_str] 324 325 def get_at_name(self,tag):#获取名称(变量、类型等) 326 if 'DW_AT_name' not in tag.at_list: 327 return None 328 result=re.findall(r'[\w\s]+$',tag.at_list['DW_AT_name'].val_attr.strip()) 329 if result: 330 return result[0].strip() 331 return None 332 333 def get_at_type(self,tag):#获取入口名 334 if 'DW_AT_type' not in tag.at_list: 335 return None 336 if 'signature:' in tag.at_list['DW_AT_type'].val_attr: 337 result = re.findall(r'signature:(\s\w+)',tag.at_list['DW_AT_type'].val_attr.strip()) 338 if result[0].strip() not in _g_parse_ctrl.sign_entry_by_id: 339 return None 340 entry_str = _g_parse_ctrl.sign_entry_by_id[result[0].strip()] 341 return entry_str 342 result = re.findall('[<]([\w\s]+)[>]$',tag.at_list['DW_AT_type'].val_attr.strip()) 343 entry_str = result[0][2:] 344 return entry_str 345 346 def get_at_byte_size(self,tag):#获取bytesize(类型) 347 if tag.type_str == "DW_TAG_pointer_type": 348 return 4 349 if 'DW_AT_byte_size' not in tag.at_list: 350 return None 351 str = tag.at_list['DW_AT_byte_size'].val_attr 352 return int(str,0) 353 354 def get_at_bit_size(self,tag):#获取bytesize(类型) 355 if 'DW_AT_bit_size' not in tag.at_list: 356 return None 357 str = tag.at_list['DW_AT_bit_size'].val_attr 358 return int(str,0) 359 360 def get_at_data_member_location(self,tag):#获取member相对偏移 361 if 'DW_AT_data_member_location' not in tag.at_list: 362 return None 363 str = tag.at_list['DW_AT_data_member_location'].val_attr 364 return int(str,0) 365 366 def get_at_count(self,tag):#数组长度 367 if 'DW_AT_count' not in tag.at_list: 368 return None 369 str = tag.at_list['DW_AT_count'].val_attr 370 if (str.startswith('<')): 371 return None 372 return int(str,0) 373 374 def get_at_location(self,tag): 375 if 'DW_AT_location' not in tag.at_list: 376 return None 377 str = tag.at_list['DW_AT_location'].val_attr.strip() 378 379 result = re.findall(r'DW_OP_addr:(\s\w+)',str) 380 if result: 381 #print(str,'------------',result[0]) 382 #print(str,' result=',result[0]) 383 return int(result[0],16) 384 else: 385 #print(str,' result=None') 386 return None 387 388 def get_root_tag(self,tag):#查找一个typedef类型的根类型 389 if tag.type_str != 'DW_TAG_typedef': 390 return tag 391 392 at_name = self.get_at_name(tag) 393 if at_name=='td_void' or at_name=='MC_VOID':#特殊情况 394 return tag 395 396 entry_str = self.get_at_type(tag) 397 if entry_str==None:#特殊情况td_void 398 return None 399 print("[ASSERT][LINE=%d]"%(sys._getframe().f_lineno),tag.entry_str) 400 assert(False) 401 new_tag = self.get_tag_by_entry_name(entry_str) 402 if new_tag==None: 403 print("[ASSERT][LINE=%d]"%(sys._getframe().f_lineno),tag.entry_str) 404 assert(False) 405 return self.get_root_tag(new_tag) 406 407 def byte_size_2_c_type_name(self,byte_size):#根据类型size转基础类型(枚举转换) 408 if byte_size==1: 409 return 'td_u8' 410 elif byte_size==2: 411 return 'td_u16' 412 elif byte_size == 4: 413 return 'td_u32' 414 elif byte_size==8: 415 return 'c_ulonglong' 416 return None 417 418 def process_phase1_base_type(self,tag): 419 at_name = self.get_at_name(tag) 420 tag.at_name = at_name 421 at_name = self.conver_base_name(at_name) 422 tag.c_type_name = at_name 423 tag.c_type_root_name = at_name 424 tag.byte_size = self.get_at_byte_size(tag) 425 tag.root_tag = tag 426 #self.print_tag_info(tag,0) 427 428 def process_phase1_enumeration_type(self,tag): 429 at_name = self.get_at_name(tag) 430 tag.at_name = at_name 431 tag.byte_size = self.get_at_byte_size(tag) 432 tag.c_type_name = self.byte_size_2_c_type_name(tag.byte_size) 433 tag.c_type_root_name = tag.c_type_name 434 tag.root_tag = tag 435 #self.print_tag_info(tag,0) 436 def process_phase1_pointer_type(self,tag): 437 tag.byte_size = 4 438 tag.c_type_name = 'td_u32' 439 tag.c_type_root_name = 'td_u32' 440 tag.root_tag = tag 441 #self.print_tag_info(tag,0) 442 443 def process_phase1_structure_type(self,tag): 444 at_name = self.get_at_name(tag) 445 tag.byte_size = self.get_at_byte_size(tag) 446 tag.at_name = at_name 447 if tag.at_name==None: 448 tag.random_name = self.create_random_name() 449 tag.c_type_name = tag.random_name 450 tag.c_type_root_name = tag.random_name 451 tag.root_tag = tag 452 else: 453 tag.c_type_name = tag.at_name 454 tag.c_type_root_name = tag.at_name 455 tag.root_tag = tag 456 #self.print_tag_info(tag,0) 457 458 def process_phase1_union_type(self,tag): 459 at_name = self.get_at_name(tag) 460 tag.byte_size = self.get_at_byte_size(tag) 461 tag.at_name = at_name 462 if tag.at_name==None: 463 tag.random_name = self.create_random_name() 464 tag.c_type_name = tag.random_name 465 tag.c_type_root_name = tag.random_name 466 tag.root_tag = tag 467 else: 468 tag.c_type_name = tag.at_name 469 tag.c_type_root_name = tag.at_name 470 tag.root_tag = tag 471 #self.print_tag_info(tag,0) 472 473 def process_phase1_type_def(self,tag): 474 at_name = self.get_at_name(tag) 475 tag.at_name = at_name 476 if tag.at_name==None: 477 return 478 assert(False) 479 tag.c_type_name = tag.at_name 480 root_tag = self.get_root_tag(tag) 481 if root_tag==None: 482 return 483 assert(False) 484 tag.byte_size = root_tag.byte_size #TBD 是否已经生成 485 tag.c_type_root_name = root_tag.c_type_root_name #TBD 是否已经生成 486 tag.root_tag = root_tag 487 #self.print_tag_info(tag,0) 488 489 def process_phase_array_type(self,tag): 490 tag.var_array = [] 491 for son in tag.son_tag_list: 492 if son.type_str == 'DW_TAG_subrange_type': 493 cnt = self.get_at_count(son) 494 if cnt==None: #特殊情况 data[] 495 cnt=0 496 tag.var_array.append(cnt) 497 #self.print_tag_info(tag,0) 498 499 def process_phase1_member_relation_tag(self,member_tag,tag): 500 entry_str = self.get_at_type(tag) 501 new_tag = self.get_tag_by_entry_name(entry_str) 502 if not new_tag: 503 return 504 if new_tag.type_str=='DW_TAG_array_type': 505 member_tag.member_array_tag = new_tag 506 elif new_tag.type_str=='DW_TAG_volatile_type' or new_tag.type_str=='DW_TAG_const_type': 507 pass 508 elif new_tag.type_str=='DW_TAG_typedef': 509 member_tag.member_type_tag = new_tag 510 elif (new_tag.type_str=='DW_TAG_base_type' 511 or new_tag.type_str=='DW_TAG_structure_type' 512 or new_tag.type_str=='DW_TAG_enumeration_type' 513 or new_tag.type_str=='DW_TAG_pointer_type' 514 or new_tag.type_str=='DW_TAG_union_type' ): 515 member_tag.member_type_tag = new_tag 516 elif (new_tag.type_str=='DW_TAG_class_type' 517 or new_tag.type_str=='DW_TAG_reference_type'): 518 member_tag.member_type_tag=None#不支持 519 return 520 else: 521 print("[new tag type can not support parse]new_tag.type_str=%s" % new_tag.type_str) 522 return 523 524 if member_tag.member_type_tag==None: 525 self.process_phase1_member_relation_tag(member_tag,new_tag) 526 #self.print_tag_info(tag,0) 527 528 def process_phase1_member(self,tag): 529 tag.member_location = self.get_at_data_member_location(tag) 530 tag.at_name = self.get_at_name(tag) 531 tag.member_name = tag.at_name 532 tag.member_bit_size = self.get_at_bit_size(tag) 533 if tag.member_name==None:#结构体内部内嵌练合体 534 tag.member_name = self.create_random_var_name() 535 if tag.member_location==None:#有些联合体没有location 536 pass 537 self.process_phase1_member_relation_tag(tag,tag) 538 #self.print_tag_info(tag,0) 539 540 def process_phase1_variable(self,tag): 541 tag.at_name = self.get_at_name(tag) 542 tag.symbol_location = self.get_at_location(tag) 543 if tag.symbol_location: 544 self.process_phase1_member_relation_tag(tag,tag) 545 self.var_symbol_dic[tag.at_name]=tag 546 #print(tag.at_name) 547 548 def process_phase1_tag(self,tag): 549 #tag_process(tag) 550 #self.print_tag_info(tag,0) 551 for son in tag.son_tag_list: 552 self.process_phase1_tag(son) 553 554 if tag.type_str == "DW_TAG_base_type": 555 self.process_phase1_base_type(tag) 556 if tag.type_str == 'DW_TAG_enumeration_type': 557 self.process_phase1_enumeration_type(tag) 558 if tag.type_str == 'DW_TAG_structure_type': 559 self.process_phase1_structure_type(tag) 560 if tag.type_str == 'DW_TAG_typedef': 561 self.process_phase1_type_def(tag) 562 if tag.type_str == 'DW_TAG_pointer_type': 563 self.process_phase1_pointer_type(tag) 564 if tag.type_str == 'DW_TAG_member': 565 self.process_phase1_member(tag) 566 if tag.type_str == 'DW_TAG_array_type': 567 self.process_phase_array_type(tag) 568 if tag.type_str == 'DW_TAG_union_type': 569 self.process_phase1_union_type(tag) 570 if tag.type_str == 'DW_TAG_variable': 571 self.process_phase1_variable(tag) 572 573 def process_phase1(self): 574 if self.parse_debug_info_phase_1==True: 575 return 576 process_list = ['DW_TAG_base_type', 577 'DW_TAG_structure_type', 578 'DW_TAG_enumeration_type', 579 'DW_TAG_pointer_type', 580 'DW_TAG_member', 581 'DW_TAG_array_type', 582 'DW_TAG_union_type', 583 'DW_TAG_variable', 584 ] 585 for tag in self.tag_list: 586 if tag.level!=1: 587 continue 588 if tag.type_str not in process_list: 589 continue 590 self.process_phase1_tag(tag) 591 592 process_list = ['DW_TAG_typedef' 593 ] 594 595 for tag in self.tag_list: 596 if tag.level!=1: 597 continue 598 if tag.type_str not in process_list: 599 continue 600 self.process_phase1_tag(tag) 601 602 self.parse_debug_info_phase_1=True 603 604 def print_tag_2_class(self,tag,lines): 605 #print("print=",tag.entry_str) 606 for line in lines: 607 print(line,file=self.class_fd) 608 609 def process_print_enumeration_type(self,tag): 610 return DEFINE_FAIL 611 612 def process_print_python_typedef(self,tag): 613 614 if tag.c_type_name=='td_void' or tag.c_type_name=='MC_VOID': 615 return DEFINE_SUCCESS 616 if tag.c_type_root_name in self.out_type_dic: 617 lines=[] 618 line='%s=%s'%(tag.c_type_name,tag.c_type_root_name) 619 lines.append(line) 620 self.print_tag_2_class(tag,lines) 621 self.out_type_dic[tag.c_type_name] = True 622 return DEFINE_SUCCESS 623 else:#原类型还没有定义,先打印原类型 624 if (tag.root_tag)==None:# TD_VOID 625 return DEFINE_FAIL 626 ret = self.print_depend_tag(tag.root_tag) 627 if ret!=DEFINE_SUCCESS: 628 return ret 629 return self.process_print_typedef(tag) 630 631 def process_print_c_typedef(self,tag): 632 #print(tag.c_type_name,tag.c_type_root_name) 633 634 if tag.c_type_name=='td_void' or tag.c_type_name=='MC_VOID': 635 return DEFINE_SUCCESS 636 if tag.c_type_root_name in self.out_type_dic: 637 lines=[] 638 line='typedef %s %s;'%(tag.c_type_root_name,tag.c_type_name) 639 lines.append(line) 640 self.print_tag_2_class(tag,lines) 641 self.out_type_dic[tag.c_type_name] = True 642 return DEFINE_SUCCESS 643 else:#原类型还没有定义,先打印原类型 644 if (tag.root_tag)==None:# TD_VOID 645 return DEFINE_FAIL 646 ret = self.print_depend_tag(tag.root_tag) 647 if ret!=DEFINE_SUCCESS: 648 return ret 649 return self.process_print_typedef(tag) 650 651 def process_print_typedef(self,tag): 652 if self.out_type=='python': 653 return self.process_print_python_typedef(tag) 654 elif self.out_type=='c': 655 return self.process_print_c_typedef(tag) 656 657 def process_print_python_member(self,tag): 658 if tag.member_type_tag==None: 659 return (DEFINE_FAIL,[]) 660 661 if tag.member_array_tag: 662 663 tmp=r'%s'%(self.get_c_type_name(tag.member_type_tag)) 664 for val in tag.member_array_tag.var_array[::-1]: 665 tmp=r'(%s*%d)'%(tmp,val) 666 line=r"('%s', %s),"%(tag.member_name,tmp) 667 ret = self.print_depend_tag(tag.member_type_tag) 668 return (ret,line) 669 elif tag.member_bit_size: 670 line=r"('%s', %s,%d),"%(tag.member_name,self.get_c_type_name(tag.member_type_tag),tag.member_bit_size) 671 ret = self.print_depend_tag(tag.member_type_tag) 672 return (ret,line) 673 else: 674 line=r"('%s', %s),"%(tag.member_name,self.get_c_type_name(tag.member_type_tag)) 675 ret = self.print_depend_tag(tag.member_type_tag) 676 return (ret,line) 677 678 def process_print_c_member(self,tag): 679 if tag.member_type_tag==None: 680 return (DEFINE_FAIL,[]) 681 682 if tag.member_array_tag: 683 tmp=r'%s %s'%(self.get_c_type_name(tag.member_type_tag),tag.member_name) 684 for val in tag.member_array_tag.var_array: 685 tmp=r'%s[%d]'%(tmp,val) 686 line=r"%s;"%(tmp) 687 ret = self.print_depend_tag(tag.member_type_tag) 688 return (ret,line) 689 elif tag.member_bit_size: 690 line=r"%s %s:%d;"%(self.get_c_type_name(tag.member_type_tag),tag.member_name,tag.member_bit_size) 691 ret = self.print_depend_tag(tag.member_type_tag) 692 return (ret,line) 693 else: 694 line=r"%s %s;"%(self.get_c_type_name(tag.member_type_tag),tag.member_name) 695 ret = self.print_depend_tag(tag.member_type_tag) 696 return (ret,line) 697 698 def process_print_member(self,tag): 699 if self.out_type=='python': 700 return self.process_print_python_member(tag) 701 elif self.out_type=='c': 702 return self.process_print_c_member(tag) 703 704 def get_c_type_name(self,tag): 705 return tag.c_type_name 706 707 def process_print_python_structure_type(self,tag): 708 lines=[] 709 line="class %s(Structure):"%(self.get_c_type_name(tag)) 710 if self.get_c_type_name(tag)=='tskTaskControlBlock' and not tag.son_tag_list: 711 return DEFINE_SUCCESS 712 if self.get_c_type_name(tag)=='QueueDefinition' and not tag.son_tag_list: 713 return DEFINE_SUCCESS 714 if tag.c_type_name in self.out_type_dic: 715 return DEFINE_SUCCESS 716 lines.append(line) 717 line=self.append_space('_fields_ = [',4) 718 lines.append(line) 719 720 for son in tag.son_tag_list: 721 if son.type_str=='DW_TAG_member': 722 (ret,line)=self.process_print_member(son) 723 if ret!= DEFINE_SUCCESS: 724 return ret 725 line=self.append_space(line,8) 726 lines.append(line) 727 728 line=self.append_space(']',4) 729 lines.append(line) 730 self.print_tag_2_class(tag,lines) 731 self.out_type_dic[tag.c_type_name] = True 732 return DEFINE_SUCCESS 733 734 def process_print_c_structure_type(self,tag): 735 lines=[] 736 line="typedef struct {" 737 lines.append(line) 738 739 for son in tag.son_tag_list: 740 if son.type_str=='DW_TAG_member': 741 (ret,line)=self.process_print_member(son) 742 if ret!= DEFINE_SUCCESS: 743 return ret 744 line=self.append_space(line,4) 745 lines.append(line) 746 747 line=self.append_space('}%s;'%(self.get_c_type_name(tag)),0) 748 lines.append(line) 749 self.print_tag_2_class(tag,lines) 750 self.out_type_dic[tag.c_type_name] = True 751 return DEFINE_SUCCESS 752 753 def process_print_structure_type(self,tag): 754 if self.out_type=='python': 755 return self.process_print_python_structure_type(tag) 756 elif self.out_type=='c': 757 return self.process_print_c_structure_type(tag) 758 759 def process_print_python_union_type(self,tag): 760 lines=[] 761 line="class %s(Union):"%(self.get_c_type_name(tag)) 762 lines.append(line) 763 line=self.append_space('_fields_ = [',4) 764 lines.append(line) 765 766 for son in tag.son_tag_list: 767 if son.type_str=='DW_TAG_member': 768 (ret,line)=self.process_print_member(son) 769 if ret!= DEFINE_SUCCESS: 770 return ret 771 line=self.append_space(line,8) 772 lines.append(line) 773 774 line=self.append_space(']',4) 775 lines.append(line) 776 self.print_tag_2_class(tag,lines) 777 self.out_type_dic[tag.c_type_name] = True 778 return DEFINE_SUCCESS 779 780 def process_print_c_union_type(self,tag): 781 lines=[] 782 line="typedef union {" 783 lines.append(line) 784 for son in tag.son_tag_list: 785 if son.type_str=='DW_TAG_member': 786 (ret,line)=self.process_print_member(son) 787 if ret!= DEFINE_SUCCESS: 788 return ret 789 line=self.append_space(line,4) 790 lines.append(line) 791 792 line=self.append_space('}%s;'%(self.get_c_type_name(tag)),0) 793 lines.append(line) 794 self.print_tag_2_class(tag,lines) 795 self.out_type_dic[tag.c_type_name] = True 796 return DEFINE_SUCCESS 797 798 def process_print_union_type(self,tag): 799 if self.out_type=='python': 800 return self.process_print_python_union_type(tag) 801 elif self.out_type=='c': 802 return self.process_print_c_union_type(tag) 803 804 def print_tag(self,tag): 805 ret=DEFINE_SUCCESS 806 if self.get_c_type_name(tag)!='tskTaskControlBlock' and self.get_c_type_name(tag)!='QueueDefinition' and tag.c_type_name in self.out_type_dic: 807 return DEFINE_SUCCESS 808 if tag.type_str == "DW_TAG_enumeration_type": 809 ret = self.process_print_enumeration_type(tag) 810 elif tag.type_str == "DW_TAG_typedef": 811 ret = self.process_print_typedef(tag) 812 elif tag.type_str == "DW_TAG_structure_type": 813 ret = self.process_print_structure_type(tag) 814 elif tag.type_str == "DW_TAG_union_type": 815 ret = self.process_print_union_type(tag) 816 else: 817 return DEFINE_FAIL 818 return ret 819 820 def print_depend_tag(self,tag): 821 #print("depend=",tag.entry_str) 822 ret = self.print_tag(tag) 823 if ret!=DEFINE_SUCCESS: 824 pass 825 else: 826 pass 827 return ret 828 829 def print_enter_tag(self,tag): 830 #print('enter=',tag.entry_str) 831 ret = self.print_tag(tag) 832 if ret!=DEFINE_SUCCESS: 833 pass 834 else: 835 pass 836 return ret 837 838 def process_phase2(self,out_file,language,type_name_list): 839 _g_parse_ctrl.out_type=language 840 self.out_type_dic={} 841 print("out_file:") 842 print(out_file) 843 with open(out_file,'w+') as fp: 844 _g_parse_ctrl.class_fd = fp 845 self.print_root_basic_type(_g_parse_ctrl.class_fd) 846 process_list = ['DW_TAG_structure_type', 847 'DW_TAG_enumeration_type', 848 'DW_TAG_typedef', 849 'DW_TAG_pointer_type', 850 'DW_TAG_union_type', 851 ] 852 for tag in self.tag_list: 853 if tag.level!=1: 854 continue 855 if tag.type_str not in process_list: 856 continue 857 if type_name_list!=None and (tag.c_type_name not in type_name_list): 858 continue 859 self.print_enter_tag(tag) 860 861 def print_var_array(self,bin,type_tag): 862 pass 863 864 def print_var_type(self,bin,type_tag): 865 tag = type_tag.root_tag 866 print(tag.entry_str) 867 if tag.type_str=='DW_TAG_union_type': 868 pass 869 870 def print_g_var(self,var_name): 871 tag=None 872 arry_tag=None 873 if var_name in self.var_symbol_dic: 874 tag = self.var_symbol_dic[var_name] 875 if tag==None: 876 return 877 878 if tag.member_array_tag: 879 arry_tag=tag.member_array_tag 880 for x in arry_tag.var_array: 881 print(x) 882 883 bin = bytearray(108) 884 self.print_var_type(bin,tag.member_type_tag) 885 print(tag.at_name) 886 887 def process_phase_0(self,file): 888 """读取debug info file,生成通用tag信息 889 Args 890 file: debug info file路径 891 return 892 """ 893 if self.parse_debug_info_phase_0==True: 894 return 895 with open(file,'r') as fp: 896 lines=fp.readlines() 897 self.parse_debug_info_lines(lines) 898 self.parse_debug_info_phase_0=True 899 900 def parase_debug_types(self, line, sign): 901 if('Compilation Unit' in line): 902 result = line.split(' ') 903 sign.sign_entry = int(result[4][:-1],16) 904 if('Signature:' in line): 905 result = line.split(':') 906 sign.signature = result[1].strip() 907 if('Type Offset:' in line): 908 result = line.split(':') 909 sign.sign_entry += int(result[1].strip(), 16) 910 self.sign_entry_by_id[sign.signature] = '{:08X}'.format(sign.sign_entry + int('0x10000000', 16)) 911 sign.signature = None 912 sign.sign_entry = 0 913 def parse_debug_info_lines(self,lines): 914 pass_st_lines=['application.elf','wstp.elf','tstp.elf','bt.elf','Contents of the','Compilation Unit', 915 'Length:','Version:','Abbrev Offset:','Pointer Size:', 'Signature', 'Type Offset','$'] 916 917 tag = None 918 new_lines = [] 919 sign = Signature() 920 for line in lines: 921 line = line.strip(); 922 if('debug_types' in line): 923 _g_parse_ctrl.debug_type = True 924 if('debug_info' in line): 925 _g_parse_ctrl.debug_type = False 926 if _g_parse_ctrl.debug_type: 927 self.parase_debug_types(line, sign) 928 if(self.match_line_list(line,pass_st_lines)): 929 continue 930 if re.match('[<]\w+[>][<]\w+[>]:',line):#tag start line 931 if tag: 932 _g_parse_ctrl.append_tag(tag) 933 tag = Tag() 934 self.parase_debug_info_tag_start_line(line,tag) 935 else: 936 self.parase_debug_info_tag_other_line(line,tag) 937 _g_parse_ctrl.append_tag(tag) 938 939 def parase_debug_info_tag_start_line(self,line,tag): 940 result = re.findall(r'[<](.*?)[>]',line)#取<>中的数据 941 tag.level_str = result[0] 942 if _g_parse_ctrl.debug_type == True: 943 tag.entry_str = '{:08X}'.format(int(result[1], 16) + int('0x10000000', 16)) 944 else: 945 tag.entry_str = result[1] 946 tag.level = int(tag.level_str,10) 947 result = re.findall(r'[(](.*?)[)]', line)#取()中的数据 948 if(result): 949 tag.type_str = result[0] 950 _g_parse_ctrl.stat_add_tag_type(tag) 951 952 def parase_debug_info_tag_other_line(self,line,tag): 953 attr = Attribute(); 954 result = re.findall(r'^[<](.*?)[>]',line)#取第一个<>中的数据 955 # attr.entry_str = result[0] 956 if _g_parse_ctrl.debug_type == True: 957 attr.entry_str = '{:08X}'.format(int(result[0], 16) + int('0x10000000', 16)) 958 else: 959 attr.entry_str = result[0] 960 result = re.findall('DW_AT_\w+',line)#取DW_AT_xxx 961 attr.type_str = result[0] 962 result = re.findall('DW_AT_\w+\s*:([\s,\S]*)',line) 963 attr.val_attr = result[0].strip() 964 if attr.type_str == "DW_AT_type" and _g_parse_ctrl.debug_type == True: 965 result = re.findall('[<]([\w\s]+)[>]$', attr.val_attr.strip()) 966 if result != []: 967 entry_str = result[0][2:] 968 attr.val_attr = '<0x{:08X}>'.format(int(entry_str, 16) + int('0x10000000', 16)) 969 _g_parse_ctrl.stat_add_attr_type(attr) 970 tag.at_list[attr.type_str]=attr 971 972 def match_line_list(self,line,mach_list): 973 for x in mach_list: 974 if re.match(x,line): 975 return True 976 return False 977 978 def parse_nm_file(self,file,dic): 979 """生成symbol字典 980 Args 981 file: nm file路径 982 dic:symbol字典 983 return 984 """ 985 if self.symbol_dic_init==True: 986 return 987 with open(file,'r') as fp: 988 lines=fp.readlines() 989 for line in lines: 990 line=line.strip() 991 if len(line)==0: 992 continue 993 list = line.split('|') 994 if len(list)!=7: 995 continue 996 997 sysmbol = Sysmbol() 998 sysmbol.key_name = list[0].strip() 999 sysmbol.addr = int(list[1].strip(),16) 1000 sysmbol.class_type = list[2].strip() 1001 sysmbol.type = list[3].strip() 1002 if len(list[4].strip()): 1003 sysmbol.size = int(list[4].strip(),16) 1004 sysmbol.section = list[6].strip() 1005 sysmbol.guess_size=0 1006 1007 dic[sysmbol.key_name] = sysmbol 1008 if sysmbol.size: 1009 pass 1010 else: 1011 pass 1012 self.symbol_dic_init = True 1013 1014def tag_cmn_attr_process(tag): 1015 if 'DW_AT_type' in tag.at_list: 1016 str = tag.at_list['DW_AT_type'].val_attr.strip() 1017 result = re.search('[<](\w*)[>]',str) 1018 input("yyyyyyyy") 1019 1020def tag_process_variable(tag): 1021 if 'DW_AT_name' in tag.at_list: 1022 str = tag.at_list['DW_AT_name'].val_attr 1023 result = re.search('\w+$',str) 1024 tag.at_name=result[0] 1025 1026 if 'DW_AT_location' in tag.at_list: 1027 str = tag.at_list['DW_AT_location'].val_attr 1028 result=re.findall(r'DW_OP_addr:\s*(\w*)',str) 1029 if result: 1030 tag.op_addr=int(result[0],16) 1031 1032def _parse_get_symbol_info(var_name): 1033 if var_name not in _g_parse_ctrl.symbol_dic: 1034 return None 1035 return _g_parse_ctrl.symbol_dic[var_name] 1036 1037def _parse_get_u32_symbol_val(name): 1038 addr = parse_get_symbol_addr(name) 1039 obj=parse_memory_2_class(addr,c_uint,4) 1040 addr=obj.value 1041 return addr 1042 1043def _parse_get_symbol_addr(var_name): 1044 symbol=parse_get_symbol_info(var_name) 1045 if symbol==None: 1046 return None 1047 return symbol.addr 1048 1049def _parse_addr_2_function_name(addr): 1050 for key in _g_parse_ctrl.symbol_dic: 1051 symbol = _g_parse_ctrl.symbol_dic[key] 1052 if symbol.type=='FUNC' and symbol.addr==addr: 1053 return symbol.key_name 1054 return None 1055 1056def _parse_addr_in_2_function_name(addr): 1057 for key in _g_parse_ctrl.symbol_dic: 1058 symbol = _g_parse_ctrl.symbol_dic[key] 1059 size = symbol.size if symbol.size!=None else symbol.guess_size 1060 if symbol.type=='FUNC' and addr>=symbol.addr and addr < (symbol.addr+size): 1061 return symbol.key_name 1062 return None 1063 1064def get_array_and_type_info(tag,member_tag): 1065 entry_str = _g_parse_ctrl.get_at_type(tag) 1066 if entry_str == None: 1067 member_tag.member_type_tag=None#不支持 1068 return 1069 new_tag = _g_parse_ctrl.get_tag_by_entry_name(entry_str) 1070 if new_tag.type_str=='DW_TAG_array_type': 1071 member_tag.member_array_tag = new_tag 1072 elif new_tag.type_str=='DW_TAG_volatile_type' or new_tag.type_str=='DW_TAG_const_type': 1073 pass 1074 elif new_tag.type_str=='DW_TAG_typedef': 1075 member_tag.member_type_tag = new_tag 1076 elif (new_tag.type_str=='DW_TAG_base_type' 1077 or new_tag.type_str=='DW_TAG_structure_type' 1078 or new_tag.type_str=='DW_TAG_enumeration_type' 1079 or new_tag.type_str=='DW_TAG_pointer_type' 1080 or new_tag.type_str=='DW_TAG_union_type' ): 1081 member_tag.member_type_tag = new_tag 1082 elif new_tag.type_str=='DW_TAG_class_type': 1083 member_tag.member_type_tag=None#不支持 1084 return 1085 else: 1086 print("[ASSERT][LINE=%d]"%(sys._getframe().f_lineno),member_tag.entry_str) 1087 assert(False) 1088 1089 if member_tag.member_type_tag==None: 1090 get_array_and_type_info(member_tag,new_tag) 1091 1092def _traverse_g_var(global_file): 1093 temp_dic_a={} 1094 temp_dic_b={} 1095 with open(global_file, "w+") as var_fp: 1096 for key in _g_parse_ctrl.symbol_dic: 1097 symbol = _g_parse_ctrl.symbol_dic[key] 1098 if symbol.type=='OBJECT': 1099 temp_dic_a[symbol.key_name]=1 1100 pass 1101 1102 for tag in _g_parse_ctrl.tag_list: 1103 if tag.type_str!='DW_TAG_variable': 1104 continue 1105 if tag.level!=1: 1106 continue 1107 at_name=_g_parse_ctrl.get_at_name(tag) 1108 if at_name not in _g_parse_ctrl.symbol_dic: 1109 continue 1110 get_array_and_type_info(tag,tag) 1111 if(tag.member_array_tag): 1112 _g_parse_ctrl.process_phase_array_type(tag.member_array_tag) 1113 if(tag.member_array_tag and tag.member_type_tag): 1114 print("%s|0x%x|%s|%s|"%(at_name,_g_parse_ctrl.symbol_dic[at_name].addr,_g_parse_ctrl.symbol_dic[at_name].size,tag.member_type_tag.c_type_name),tag.member_array_tag.var_array,file=var_fp) 1115 elif (tag.member_type_tag): 1116 print("%s|0x%x|%s|%s"%(at_name,_g_parse_ctrl.symbol_dic[at_name].addr,_g_parse_ctrl.symbol_dic[at_name].size,tag.member_type_tag.c_type_name),file=var_fp) 1117 else: 1118 print("%s|0x%x|%s|%s"%(at_name,_g_parse_ctrl.symbol_dic[at_name].addr,_g_parse_ctrl.symbol_dic[at_name].size,''), file=var_fp) 1119 1120def parse_elf_step_1(debug_info_file,out_class_file,out_ctype_file,nm_file,global_file,diag_dir,xml_file): 1121 type_name_list = parse_tools_xml(xml_file, debug_info_file, diag_dir) 1122 _g_parse_ctrl.parse_nm_file(nm_file,_g_parse_ctrl.symbol_dic) 1123 _g_parse_ctrl.process_phase_0(debug_info_file) 1124 _g_parse_ctrl.process_phase1() 1125 _g_parse_ctrl.process_phase2(out_class_file,'python',None) 1126 _g_parse_ctrl.process_phase2(out_ctype_file,'c',type_name_list) 1127 _traverse_g_var(global_file) 1128 uapi_register_function('get_symbol_info',_parse_get_symbol_info) 1129 uapi_register_function('get_u32_symbol_val',_parse_get_u32_symbol_val) 1130 uapi_register_function('get_symbol_addr',_parse_get_symbol_addr) 1131 uapi_register_function('addr_2_function_name',_parse_addr_2_function_name) 1132 uapi_register_function('addr_in_2_function_name',_parse_addr_in_2_function_name) 1133 1134def parse_elf_step_2(nm_file): 1135 _g_parse_ctrl.parse_nm_file(nm_file,_g_parse_ctrl.symbol_dic) 1136 uapi_register_function('get_symbol_info',_parse_get_symbol_info) 1137 uapi_register_function('get_u32_symbol_val',_parse_get_u32_symbol_val) 1138 uapi_register_function('get_symbol_addr',_parse_get_symbol_addr) 1139 uapi_register_function('addr_2_function_name',_parse_addr_2_function_name) 1140 uapi_register_function('addr_in_2_function_name',_parse_addr_in_2_function_name) 1141 1142_g_parse_ctrl = ParseCtrl() 1143 1144 1145