inwudriver-weibo/target/socbuilder/scripts/arm_thumb_asm_check.py

118 lines
4.7 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
# coding=utf-8
import json
import re
import sys
# 从符号表fixrom.sym获取非函数内容, 保存到例外配置文件
# 参数(fixrom.sym路径, 例外配置文件路径)
def GetDataFixrom(sym_path, except_file):
result = {}
# 变量列表
var_list = ['crc16_tab', '_ctype', 'crc16_tab', '__rom_copy_start', '__rom_copy_ram_start', '__rom_bss_end']
with open(sym_path, 'r') as fixrom_data:
for line in fixrom_data.readlines():
# 正则匹配,提取变量/函数名和地址
re_bds = "(.*) = (.*);"
p = re.findall(re_bds, line, re.S)
# 字符串转数字
tmp = int(p[0][1], 16)
# 初步筛选 堆,栈,BSS+DATA段的内容
if ((tmp >= 0x02017000 and tmp <= 0x02039000) or \
(tmp >= 0x0203D000 and tmp <= 0x0203F000) or \
(tmp >= 0x0203f000 and tmp <= 0x02040000) or\
(tmp >= 0x00010800 and tmp <= 0x00040800)):
# 根据名字再次筛选非函数内容
if p[0][0][0:2] == "g_" or \
p[0][0] in var_list:
result[p[0][0]] = p[0][1]
# 将字典里的内容根据键值对,写入到例外配置文件
with open(except_file, 'w') as wr_j:
json.dump(result, wr_j)
return
# 从符号表Firmware_Base.sym获取非函数内容保存到例外配置文件
# 参数(Firmware_Base.sym路径, 例外配置文件路径)
def GetDataRom(sym_path, except_file):
result = {}
# 变量列表
with open(sym_path, 'r') as fixrom_data:
for line in fixrom_data.readlines():
# 正则匹配,提取变量/函数名和地址
re_bds = "(.*) = (.*);"
p = re.findall(re_bds, line, re.S)
tmp = (int(p[0][1], 16))
# 根据二进制范围,提取 DATA/BSS段的内容,放到字典中
if ((tmp >= 0x02000400 and tmp <= 0x02003400) or \
(tmp >= 0x02001000 and tmp <= 0x02001420) or \
(p[0][0][0:2] == 'g_')):
result[p[0][0]] = p[0][1]
# 将字典里的内容根据键值对,写入到例外配置文件
with open(except_file, 'w') as wr_j:
json.dump(result, wr_j)
return
# 功能:从asm文件中提取16进制数
# 参数:output路径
# 返回值: 返回.word后的十六进制数列表
def get_asm_data(asm_path):
# 用来存放 .word 后的十六进制数
word_list = []
with open(asm_path, 'r') as fp:
# 逐行读取, 并提取 .word 后面的十六进制数
for word in fp.readlines():
re_bds = ".word (.*)\n"
p = re.findall(re_bds, word, re.S)
# 正则匹配成功,把十六进制数放到列表里
if len(p) > 0:
word_list.append(p[0])
return word_list
# 参数: asm文件路径, 符号表路径, 例外配置文件路径
def ArmThumbAsmCheck(asm_path, symbol_table_path, exception_file_path):
# 从.asm文件获取 .word后的地址,返回值为列表
word_list = get_asm_data(asm_path)
# 相同函数的报错信息,只输出一次
flag_print = []
# 根据.word后面的地址。在符号表文件中和例外配置文件中查找是否存在
with open(symbol_table_path, 'r') as sym_fp:
with open(exception_file_path, 'r') as expt_fp:
expt_text = expt_fp.read()
sym_text = sym_fp.read()
for word in word_list:
if word in sym_text:
if word not in expt_text:
re_bds = '(.*) = ' + word
func = re.findall(re_bds, sym_text)[0]
print('%-30s%-30s' %(func,"Error函数中调用rom化的函数不符合当先rom化函数调用规范"))
return -1;
return
if __name__ == '__main__':
# start_time = time.time()
# asm文件路径
asm_path = sys.argv[1]
# 符号表路径
sym_path = sys.argv[2]
# 例外配置文件路径
expt_file = sys.argv[3]
try:
f_exec = open(expt_file, 'r')
f_exec.close()
except IOError:
# 从符号表fixrom.sym获取非函数内容, 保存到例外配置文件
if sym_path[-10:]=="fixrom.sym":
GetDataFixrom(sym_path, expt_file)
elif sym_path[-17:]=="Firmware_Base.sym":
GetDataRom(sym_path, expt_file)
# 测试函数
ret = ArmThumbAsmCheck(asm_path, sym_path, expt_file)
if ret==-1:
sys.exit(-1)
# end_time = time.time()
# print('(>_<)执行时间: ' + str(end_time - start_time))