为了方便调试 C6000 DSP,我需要获取 DSP 内部所有变量的地址和大小。TI 的 cg_xml 工具包没有提供变量大小的信息,所以我写了这个 Python 脚本,从 .out 文件中提取变量信息并导出为 .csv 文件。
说明
这个脚本包括:
首先,用 ofd6x 把 .out 文件的信息导出为 xml 信息。
然后,用 ElementTree 处理 xml。
最后,生成 csv 文件。
<elf32_sym> 标签包含符号的信息,这些标签位于路径 object_file/elf/section_table/section/symbol_table/ 下。 <elf32_sym> 的内容类似这样:
<elf32_sym>
<index>0x11cf</index>
<st_name>0xce40</st_name>
<st_name_string>VariableName</st_name_string>
<st_value>0x82825c</st_value>
<st_size>0x2</st_size>
<st_bind>STB_GLOBAL</st_bind>
<st_type>STT_OBJECT</st_type>
<st_visibility>STV_HIDDEN</st_visibility>
<st_shndx>0x7</st_shndx>
<st_shndx_string>.bss</st_shndx_string>
</elf32_sym>这个链接详细介绍了符号表节(Symbol Table Section)。注意,STT_OBJECT 对应数据对象,如变量、数组等。STT_COMMON 表示一个未初始化的公共块,其处理方式与 STT_OBJECT 完全相同。
若 .out 文件中包含非 ASCII 字符的路径,ofd6x 生成的 xml 可能会含有一些无效字符。下面这句代码用于删除这些无效字符:
output.decode('utf-8','ignore').encode('utf-8')Python 脚本
import xml.etree.ElementTree as ET
import csv
import subprocess
import sys
import os
if len(sys.argv) != 2:
sys.exit()
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
filename = sys.argv[1]
output = subprocess.Popen([resource_path("ofd6x.exe"), "-xg", filename], stdout=subprocess.PIPE).communicate()[0]
root = ET.fromstring(output.decode('utf-8','ignore').encode('utf-8'))
def get_name(sym):
return sym.find('st_name_string').text
def get_type(sym):
return sym.find('st_type').text
def get_addr(sym):
return sym.find('st_value').text
def get_size(sym):
return sym.find('st_size').text
def get_bind(sym):
return sym.find('st_bind').text
def get_visibility(sym):
return sym.find('st_visibility').text
def get_shndx(sym):
return sym.find('st_shndx_string').text
with open(filename+'_syms.csv', 'w', newline='') as csvfile:
fieldnames = ['name', 'addr', 'addr10', 'size', 'section','bind', 'technblogy.com']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for sym in root.findall('object_file/elf/section_table/section/symbol_table/elf32_sym'):
if (get_type(sym)=='STT_OBJECT' or get_type(sym)=='STT_COMMON') and get_name(sym)[0]!='$':
c = {}
c['name'] = get_name(sym)
c['addr'] = get_addr(sym)
c['addr10'] = int(get_addr(sym),16)
c['size'] = int(get_size(sym),16)
c['section'] = get_shndx(sym)
c['bind'] = get_bind(sym)
writer.writerow(c)
参考
Software Development Organization (SDO) Applications Packages
Symbol Table Section – Linker and Libraries Guide
python – ElementTree and unicode – Stack Overflow
python – Bundling data files with PyInstaller (–onefile) – Stack Overflow
0 条评论