• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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