OVMS3-idf/tools/esp_app_trace/pylibelf/iterators/__init__.py
Alexey Gerenkov 55f1a63faf esp32: Adds functionality for application tracing over JTAG
- Implements application tracing module which allows to send arbitrary
   data to host over JTAG. This feature is useful for analyzing
   program modules behavior, dumping run-time application data etc.
 - Implements printf-like logging functions on top of apptrace module.
   This feature is a kind of semihosted printf functionality with lower
   overhead and impact on system behaviour as compared to standard printf.
2017-04-17 23:26:29 +03:00

217 lines
5.2 KiB
Python

import sys
import os
from .. import *
from ..constants import *
from ..types import *
from ..util import *
from ctypes import *
def sections(elf, **kwargs):
i = None
ndx = 0 # we skip the first null section
if 'info' in kwargs:
if (isinstance(kwargs['info'], Elf_Scn)):
info = elf_ndxscn(kwargs['info'])
else:
info = kwargs['info']
else:
info = None
while 1:
i = elf_nextscn(elf, i)
ndx += 1
if (not bool(i)):
break
try:
if ('name' in kwargs and section_name(elf, i) != kwargs['name']):
continue
if ('type' in kwargs and section_type(elf, i) != kwargs['type']):
continue
if ('link' in kwargs and section_link(elf, i) != kwargs['link']):
continue
if (info != None and section_hdr(elf, i).sh_info != info):
continue
except ValueError:
print "Error iterating over section ", i
continue
if ('ndx' in kwargs and kwargs['ndx']):
yield (ndx, i.contents)
else:
yield i.contents
def shdrs(elf):
i = None
while 1:
i = elf_nextscn(elf, i)
if (not bool(i)):
break
yield select(elf, 'getshdr')(i.contents).contents
def phdrs(elf):
phdrTbl = select(elf, "getphdr")(elf)
ehdr = select(elf, "getehdr")(elf).contents
phdrCnt = ehdr.e_phnum
for i in xrange(0, phdrCnt):
yield phdrTbl[i]
def data(elf_scn):
i = None
while 1:
i = elf_getdata(elf_scn, i)
if (not bool(i)):
break
yield i.contents
def strings(v):
if (isinstance(v, Elf_Data)):
strtab_data = v
size = strtab_data.d_size
buf = cast(strtab_data.d_buf, POINTER(c_char))
start = 0;
while start < size:
end = start;
while buf[end] != '\x00': end += 1
yield (strtab_data.d_off + start, buf[start:end])
start = end+1
elif (isinstance(v, Elf_Scn)):
for d in data(v):
strtab_data = d
size = strtab_data.d_size
buf = cast(strtab_data.d_buf, POINTER(c_char))
start = 0;
while start < size:
end = start;
while buf[end] != '\x00': end += 1
yield (strtab_data.d_off + start, buf[start:end])
start = end+1
def arr_iter(data, itemT, ind = False):
size = data.d_size
if size % sizeof(itemT) != 0:
raise Exception("Data size not a multiple of symbol size!")
buf = cast(data.d_buf, POINTER(itemT))
nelems = size / sizeof(itemT)
for i in xrange(0, nelems):
if ind:
yield (i, buf[i])
else:
yield buf[i]
def syms(elf, v = None):
symT = Elf32_Sym if (is32(elf)) else Elf64_Sym
if v == None:
for s in sections(elf):
hdr = section_hdr(elf, s)
if (hdr.sh_type != SHT_SYMTAB and hdr.sh_type != SHT_DYNSYM):
continue
for d in data(s):
for (ind, sym) in arr_iter(d, symT, True):
yield (ind, sym)
elif isinstance(v, Elf_Scn):
for d in data(v):
for (ind, sym) in arr_iter(d, symT, True):
yield (ind, sym)
else:
assert isinstance(v, Elf_Data)
for (ind, sym) in arr_iter(v, symT, True):
yield (ind, sym)
def rels(elf, **kwargs):
relT = Elf32_Rel if (is32(elf)) else Elf64_Rel
if 'section' in kwargs:
secl = sections(elf, type = SHT_REL, info = kwargs['section'])
else:
secl = sections(elf, type = SHT_REL)
if 'range' in kwargs:
for scn in secl:
for d in data(scn):
for rel in arr_iter(d, relT):
if (rel.r_offset >= kwargs['range'][0] and
rel.r_offset < kwargs['range'][1]):
yield (rel, section_hdr(elf, scn).sh_link)
else:
for scn in secl:
for d in data(scn):
for rel in arr_iter(d, relT):
yield (rel, section_hdr(elf, scn).sh_link)
def relas(elf, **kwargs):
relT = Elf32_Rela if (is32(elf)) else Elf64_Rela
if 'section' in kwargs:
scn = kwargs['section']
if (type(scn) == str): scn = list(sections(elf, name=scn))[0]
if (isinstance(scn, Elf_Scn)): scn = elf_ndxscn(byref(scn))
secl = list(sections(elf, type = SHT_RELA, info = scn))
else:
secl = list(sections(elf, type = SHT_RELA))
if 'range' in kwargs:
for scn in secl:
for d in data(scn):
for rel in arr_iter(d, relT):
if (rel.r_offset + rel.r_addend >= kwargs['range'][0] and
rel.r_offset + rel.r_addend < kwargs['range'][1]):
yield (rel, section_hdr(elf, scn).sh_link)
else:
addSecId = kwargs['withSectionId']==True \
if 'withSectionId' in kwargs \
else False
if not addSecId:
for scn in secl:
for d in data(scn):
for rel in arr_iter(d, relT):
yield (rel, section_hdr(elf, scn).sh_link)
else:
for scn in secl:
for d in data(scn):
for rel in arr_iter(d, relT):
yield (rel, section_hdr(elf, scn).sh_info)
def getOnlyData(scn):
d = elf_getdata(scn, None);
assert bool(elf_getdata(scn, d)) == False
return d
def dyns(elf):
relT = Elf64_Dyn
for scn in sections(elf, name=".dynamic"):
for d in data(scn):
for dyn in arr_iter(d, relT):
yield dyn
def elfs(fname):
fd = os.open(fname, os.O_RDONLY)
ar = elf_begin(fd, ELF_C_READ, None)
i = None
while 1:
i = elf_begin(fd, ELF_C_READ, ar)
if (not bool(i)):
break
yield i
elf_end(ar)
os.close(fd)