scripts/symbolize.py: print ELF sections after MMU region information
When processing a user TA abort dump, list the ELF sections that are
mapped in each MMU region. For example (the lines modified by this
patch are prefixed with >>):
User TA undef-abort at address 0x10574e
fsr 0x00000000 ttbr0 0x0e07a06a ttbr1 0x0e07406a cidr 0x1
cpu #0 cpsr 0x60000030
r0 0x20000013 r4 0x0013a6bc r8 0x00000000 r12 0x0e07dd88
r1 0x00000033 r5 0x00121fd3 r9 0x00000000 sp 0x001026cc
r2 0x0010581f r6 0x00102590 r10 0x00000000 lr 0x00105823
r3 0x00000043 r7 0x001026cc r11 0x00000000 pc 0x0010574e
Status of TA 5b9e0e40-2636-11e1-ad9e-0002a5d5c51b (0xe073b70) (active)
arch: arm load address: 0x103000 ctx-idr: 1
stack: 0x100000 10240
region 0: va 0x100000 pa 0xe21e000 size 0x3000 flags rw-
>> region 1: va 0x103000 pa 0xe100000 size 0x2e000 flags r-x .ta_head .text .rodata
>> region 2: va 0x131000 pa 0xe12e000 size 0xa000 flags r-- .rodata .ARM.extab .ARM.exidx .got .dynsym .rel.got .dynamic .dynstr .hash .rel.dyn
>> region 3: va 0x13b000 pa 0xe138000 size 0xe6000 flags rw- .data .bss
region 4: va 0 pa 0 size 0 flags ---
region 5: va 0 pa 0 size 0 flags ---
region 6: va 0 pa 0 size 0 flags ---
region 7: va 0 pa 0 size 0 flags ---
User TA undef-abort at address 0x10574e undef_instr+6 .text+10030
Call stack:
0x0010574e undef_instr at optee_test/ta/os_test/os_test.c:880
0x00105823 ta_entry_bad_mem_access at optee_test/ta/os_test/os_test.c:917
0x00105e75 TA_InvokeCommandEntryPoint at optee_test/ta/os_test/ta_entry.c:101
0x00121fb7 entry_invoke_command at optee_os/lib/libutee/arch/arm/user_ta_entry.c:207
0x00122013 __utee_entry at optee_os/lib/libutee/arch/arm/user_ta_entry.c:235
Suggested-by: Zeng Tao <prime.zeng@hisilicon.com>
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/scripts/symbolize.py b/scripts/symbolize.py
index 9599b6f..772ba2e 100755
--- a/scripts/symbolize.py
+++ b/scripts/symbolize.py
@@ -40,6 +40,8 @@
CALL_STACK_RE = re.compile('Call stack:')
STACK_ADDR_RE = re.compile(r': (?P<addr>0x[0-9a-f]+)')
ABORT_ADDR_RE = re.compile('-abort at address (?P<addr>0x[0-9a-f]+)')
+REGION_RE = re.compile('region [0-9]+: va (?P<addr>0x[0-9a-f]+) '
+ 'pa 0x[0-9a-f]+ size (?P<size>0x[0-9a-f]+)')
epilog = '''
This scripts reads an OP-TEE abort message from stdin and adds debug
@@ -157,7 +159,7 @@
cmd = self.arch_prefix('nm')
if not reladdr or not elf or not cmd:
return ''
- ireladdr = int(reladdr, 0)
+ ireladdr = int(reladdr, 16)
nm = subprocess.Popen([cmd, '--numeric-sort', '--print-size', elf],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE)
@@ -193,7 +195,7 @@
cmd = self.arch_prefix('objdump')
if not reladdr or not elf or not cmd:
return ''
- iaddr = int(reladdr, 0)
+ iaddr = int(reladdr, 16)
objdump = subprocess.Popen([cmd, '--section-headers', elf],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE)
@@ -232,6 +234,44 @@
ret += line[post:]
return ret
+ # Return all ELF sections with the ALLOC flag
+ def read_sections(self):
+ if self._sections:
+ return
+ elf = self.get_elf(self._bin)
+ cmd = self.arch_prefix('objdump')
+ if not elf or not cmd:
+ return
+ objdump = subprocess.Popen([cmd, '--section-headers', elf],
+ stdin = subprocess.PIPE,
+ stdout = subprocess.PIPE)
+ for line in iter(objdump.stdout.readline, ''):
+ try:
+ _, name, size, vma, _, _, _ = line.split()
+ except:
+ if 'ALLOC' in line:
+ self._sections.append([name, int(vma, 16), int(size, 16)])
+
+ def overlaps(self, section, addr, size):
+ sec_addr = section[1]
+ sec_size = section[2]
+ if not size or not sec_size:
+ return False
+ return (addr <= (sec_addr + sec_size - 1)) and ((addr + size - 1) >= sec_addr)
+
+ def sections_in_region(self, addr, size):
+ ret = ''
+ addr = self.subtract_load_addr(addr)
+ if not addr:
+ return ''
+ iaddr = int(addr, 16)
+ isize = int(size, 16)
+ self.read_sections()
+ for s in self._sections:
+ if self.overlaps(s, iaddr, isize):
+ ret += ' ' + s[0]
+ return ret
+
def reset(self):
self._call_stack_found = False
self._load_addr = '0'
@@ -240,6 +280,7 @@
self._addr2line = None
self._arch = None
self._saved_abort_line = ''
+ self._sections = []
def write(self, line):
if self._call_stack_found:
@@ -259,6 +300,13 @@
return
else:
self.reset()
+ match = re.search(REGION_RE, line)
+ if match:
+ addr = match.group('addr')
+ size = match.group('size')
+ self._out.write(line.strip() +
+ self.sections_in_region(addr, size) + '\n');
+ return
match = re.search(CALL_STACK_RE, line)
if match:
self._call_stack_found = True