In order to facilitate the debugging needs of C6000 DSP, I need to obtain the addresses and sizes of all variables inside the DSP. The cg_xml
package from TI does not provide variable size information, so I wrote this python script to extract variable information from the .out file and export it as a .csv file.
Description
This script contains:
First, use ofd6x
to export the .out file information as xml information.
Then, use ElementTree to process the xml.
Finally, a csv file is generated.
The <elf32_sym>
tag contains the symbols’ information. The tags are under the path object_file/elf/section_table/section/symbol_table/
. The <elf32_sym>
is like:
<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>
This link gives the detailed information of Symbol Table Section. Note that, STT_OBJECT is associated with a data object, such as a variable, an array, and so forth. STT_COMMON labels an uninitialized common block. This symbol is treated exactly the same as STT_OBJECT
.
The xml produced by ofd6x
may contain some invalid characters if the .out contains paths of non-Ascii characters. This sentence removes the invalid characters:
output.decode('utf-8','ignore').encode('utf-8')
Python Script
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)
Reference
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 Comments