blob: 48ba1c0f90e8e4a72ca8977d7ec1fccb973bddd4 [file] [log] [blame]
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +02001#!/usr/bin/env python3
Jerome Forissier1bb92982017-12-15 14:27:02 +01002# SPDX-License-Identifier: BSD-2-Clause
Jerome Forissier733a15f2017-05-19 17:40:17 +02003#
4# Copyright (c) 2017, Linaro Limited
Jerome Forissier733a15f2017-05-19 17:40:17 +02005#
Jerome Forissier733a15f2017-05-19 17:40:17 +02006
7
8import argparse
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +02009import errno
Jerome Forissier733a15f2017-05-19 17:40:17 +020010import glob
Jerome Forissier157e6212017-08-24 15:49:16 +020011import os
Jerome Forissier733a15f2017-05-19 17:40:17 +020012import re
13import subprocess
14import sys
15
Jerome Forissier733a15f2017-05-19 17:40:17 +020016CALL_STACK_RE = re.compile('Call stack:')
Joakim Becha2b984b2017-12-15 14:34:56 +010017# This gets the address from lines looking like this:
18# E/TC:0 0x001044a8
Jerome Forissier6e7c2e92018-11-14 11:02:49 +010019STACK_ADDR_RE = re.compile(
Jens Wiklander531963a2019-05-23 17:42:15 +020020 r'[UEIDFM]/(TC|LD):(\?*|[0-9]*) [0-9]* +(?P<addr>0x[0-9a-f]+)')
Jerome Forissier6e7c2e92018-11-14 11:02:49 +010021ABORT_ADDR_RE = re.compile(r'-abort at address (?P<addr>0x[0-9a-f]+)')
Jerome Forissier444c2032019-03-13 18:00:56 +010022REGION_RE = re.compile(r'region +[0-9]+: va (?P<addr>0x[0-9a-f]+) '
Jerome Forissier6e7c2e92018-11-14 11:02:49 +010023 r'pa 0x[0-9a-f]+ size (?P<size>0x[0-9a-f]+)'
Jens Wiklander531963a2019-05-23 17:42:15 +020024 r'( flags .{4} (\[(?P<elf_idx>[0-9]+)\])?)?')
Jerome Forissierae252462018-05-25 15:07:28 +020025ELF_LIST_RE = re.compile(r'\[(?P<idx>[0-9]+)\] (?P<uuid>[0-9a-f\-]+)'
Jerome Forissier6e7c2e92018-11-14 11:02:49 +010026 r' @ (?P<load_addr>0x[0-9a-f\-]+)')
Sumit Gargc90b6662019-03-28 18:24:21 +053027FUNC_GRAPH_RE = re.compile(r'Function graph')
28GRAPH_ADDR_RE = re.compile(r'(?P<addr>0x[0-9a-f]+)')
29GRAPH_RE = re.compile(r'}')
Jerome Forissier733a15f2017-05-19 17:40:17 +020030
31epilog = '''
Jerome Forissier0c5bedb2018-02-15 17:20:36 +010032This scripts reads an OP-TEE abort or panic message from stdin and adds debug
33information to the output, such as '<function> at <file>:<line>' next to each
34address in the call stack. Any message generated by OP-TEE and containing a
35call stack can in principle be processed by this script. This currently
36includes aborts and panics from the TEE core as well as from any TA.
37The paths provided on the command line are used to locate the appropriate ELF
38binary (tee.elf or Trusted Application). The GNU binutils (addr2line, objdump,
Jerome Forissierf9089762018-10-02 10:12:32 +020039nm) are used to extract the debug info. If the CROSS_COMPILE environment
40variable is set, it is used as a prefix to the binutils tools. That is, the
41script will invoke $(CROSS_COMPILE)addr2line etc. If it is not set however,
42the prefix will be determined automatically for each ELF file based on its
43architecture (arm-linux-gnueabihf-, aarch64-linux-gnu-). The resulting command
44is then expected to be found in the user's PATH.
Jerome Forissier733a15f2017-05-19 17:40:17 +020045
Jerome Forissier0c5bedb2018-02-15 17:20:36 +010046OP-TEE abort and panic messages are sent to the secure console. They look like
47the following:
Jerome Forissier733a15f2017-05-19 17:40:17 +020048
Jerome Forissier0c5bedb2018-02-15 17:20:36 +010049 E/TC:0 User TA data-abort at address 0xffffdecd (alignment fault)
Jerome Forissier733a15f2017-05-19 17:40:17 +020050 ...
Jerome Forissier0c5bedb2018-02-15 17:20:36 +010051 E/TC:0 Call stack:
52 E/TC:0 0x4000549e
53 E/TC:0 0x40001f4b
54 E/TC:0 0x4000273f
55 E/TC:0 0x40005da7
Jerome Forissier733a15f2017-05-19 17:40:17 +020056
57Inspired by a script of the same name by the Chromium project.
58
59Sample usage:
60
61 $ scripts/symbolize.py -d out/arm-plat-hikey/core -d ../optee_test/out/ta/*
62 <paste whole dump here>
63 ^D
Sumit Gargc90b6662019-03-28 18:24:21 +053064
65Also, this script reads function graph generated for OP-TEE user TA from
66/tmp/ftrace-<ta_uuid>.out file and resolves function addresses to corresponding
67symbols.
68
69Sample usage:
70
71 $ cat /tmp/ftrace-<ta_uuid>.out | scripts/symbolize.py -d <ta_uuid>.elf
72 <paste function graph here>
73 ^D
Jerome Forissier733a15f2017-05-19 17:40:17 +020074'''
75
Jerome Forissierae252462018-05-25 15:07:28 +020076
Jerome Forissier733a15f2017-05-19 17:40:17 +020077def get_args():
78 parser = argparse.ArgumentParser(
Jerome Forissier6e7c2e92018-11-14 11:02:49 +010079 formatter_class=argparse.RawDescriptionHelpFormatter,
Sumit Gargc90b6662019-03-28 18:24:21 +053080 description='Symbolizes OP-TEE abort dumps or function graphs',
Jerome Forissier6e7c2e92018-11-14 11:02:49 +010081 epilog=epilog)
Jerome Forissier733a15f2017-05-19 17:40:17 +020082 parser.add_argument('-d', '--dir', action='append', nargs='+',
Jerome Forissier1d8c2a42018-09-07 17:05:21 +020083 help='Search for ELF file in DIR. tee.elf is needed '
84 'to decode a TEE Core or pseudo-TA abort, while '
85 '<TA_uuid>.elf is required if a user-mode TA has '
86 'crashed. For convenience, ELF files may also be '
87 'given.')
Jerome Forissier5f7df502018-02-15 16:57:55 +010088 parser.add_argument('-s', '--strip_path', nargs='?',
Jerome Forissier1d8c2a42018-09-07 17:05:21 +020089 help='Strip STRIP_PATH from file paths (default: '
90 'current directory, use -s with no argument to show '
91 'full paths)', default=os.getcwd())
Jerome Forissier733a15f2017-05-19 17:40:17 +020092
93 return parser.parse_args()
94
Jerome Forissierae252462018-05-25 15:07:28 +020095
Jerome Forissier733a15f2017-05-19 17:40:17 +020096class Symbolizer(object):
97 def __init__(self, out, dirs, strip_path):
98 self._out = out
99 self._dirs = dirs
100 self._strip_path = strip_path
101 self._addr2line = None
Jerome Forissier733a15f2017-05-19 17:40:17 +0200102 self.reset()
103
Jerome Forissier1cbf7772018-09-07 17:08:23 +0200104 def my_Popen(self, cmd):
105 try:
106 return subprocess.Popen(cmd, stdin=subprocess.PIPE,
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +0200107 stdout=subprocess.PIPE, text=True,
108 bufsize=1)
Jerome Forissier1cbf7772018-09-07 17:08:23 +0200109 except OSError as e:
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +0200110 if e.errno == errno.ENOENT:
111 print("*** Error:{}: command not found".format(cmd[0]),
112 file=sys.stderr)
Jerome Forissier1cbf7772018-09-07 17:08:23 +0200113 sys.exit(1)
114
Jerome Forissier733a15f2017-05-19 17:40:17 +0200115 def get_elf(self, elf_or_uuid):
116 if not elf_or_uuid.endswith('.elf'):
117 elf_or_uuid += '.elf'
118 for d in self._dirs:
Jerome Forissier157e6212017-08-24 15:49:16 +0200119 if d.endswith(elf_or_uuid) and os.path.isfile(d):
120 return d
Jerome Forissier733a15f2017-05-19 17:40:17 +0200121 elf = glob.glob(d + '/' + elf_or_uuid)
122 if elf:
123 return elf[0]
124
Jerome Forissierd7204312017-09-04 17:58:52 +0200125 def set_arch(self):
126 if self._arch:
127 return
Jerome Forissier6e7c2e92018-11-14 11:02:49 +0100128 self._arch = os.getenv('CROSS_COMPILE')
Etienne Carriere8a6d4a82018-10-01 09:58:31 +0200129 if self._arch:
130 return
Jerome Forissierae252462018-05-25 15:07:28 +0200131 elf = self.get_elf(self._elfs[0][0])
132 if elf is None:
133 return
134 p = subprocess.Popen(['file', self.get_elf(self._elfs[0][0])],
135 stdout=subprocess.PIPE)
136 output = p.stdout.readlines()
137 p.terminate()
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +0200138 if b'ARM aarch64,' in output[0]:
Jerome Forissierae252462018-05-25 15:07:28 +0200139 self._arch = 'aarch64-linux-gnu-'
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +0200140 elif b'ARM,' in output[0]:
Jerome Forissierae252462018-05-25 15:07:28 +0200141 self._arch = 'arm-linux-gnueabihf-'
Jerome Forissierd7204312017-09-04 17:58:52 +0200142
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200143 def arch_prefix(self, cmd):
Jerome Forissierd7204312017-09-04 17:58:52 +0200144 self.set_arch()
Jerome Forissierae252462018-05-25 15:07:28 +0200145 if self._arch is None:
146 return ''
Jerome Forissierd7204312017-09-04 17:58:52 +0200147 return self._arch + cmd
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200148
Jerome Forissierae252462018-05-25 15:07:28 +0200149 def spawn_addr2line(self, elf_name):
150 if elf_name is None:
151 return
152 if self._addr2line_elf_name is elf_name:
153 return
154 if self._addr2line:
155 self._addr2line.terminate
156 self._addr2line = None
157 elf = self.get_elf(elf_name)
158 if not elf:
159 return
160 cmd = self.arch_prefix('addr2line')
161 if not cmd:
162 return
Jerome Forissier1cbf7772018-09-07 17:08:23 +0200163 self._addr2line = self.my_Popen([cmd, '-f', '-p', '-e', elf])
Jerome Forissierae252462018-05-25 15:07:28 +0200164 self._addr2line_elf_name = elf_name
165
166 # If addr falls into a region that maps a TA ELF file, return the load
167 # address of that file.
168 def elf_load_addr(self, addr):
169 if self._regions:
170 for r in self._regions:
171 r_addr = int(r[0], 16)
172 r_size = int(r[1], 16)
173 i_addr = int(addr, 16)
174 if (i_addr >= r_addr and i_addr < (r_addr + r_size)):
175 # Found region
176 elf_idx = r[2]
177 if elf_idx is not None:
178 return self._elfs[int(elf_idx)][1]
179 return None
180 else:
181 # tee.elf
182 return '0x0'
183
184 def elf_for_addr(self, addr):
185 l_addr = self.elf_load_addr(addr)
186 if l_addr is None:
187 return None
188 if l_addr is '0x0':
189 return 'tee.elf'
190 for k in self._elfs:
191 e = self._elfs[k]
192 if int(e[1], 16) == int(l_addr, 16):
193 return e[0]
194 return None
Jerome Forissier733a15f2017-05-19 17:40:17 +0200195
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200196 def subtract_load_addr(self, addr):
Jerome Forissierae252462018-05-25 15:07:28 +0200197 l_addr = self.elf_load_addr(addr)
198 if l_addr is None:
199 return None
200 if int(l_addr, 16) > int(addr, 16):
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200201 return ''
Jerome Forissierae252462018-05-25 15:07:28 +0200202 return '0x{:x}'.format(int(addr, 16) - int(l_addr, 16))
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200203
204 def resolve(self, addr):
205 reladdr = self.subtract_load_addr(addr)
Jerome Forissierae252462018-05-25 15:07:28 +0200206 self.spawn_addr2line(self.elf_for_addr(addr))
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200207 if not reladdr or not self._addr2line:
Jerome Forissier733a15f2017-05-19 17:40:17 +0200208 return '???'
209 try:
Rouven Czerwinskibbaeed42019-08-07 20:07:00 +0200210 print(reladdr, file=self._addr2line.stdin)
Jerome Forissier733a15f2017-05-19 17:40:17 +0200211 ret = self._addr2line.stdout.readline().rstrip('\n')
212 except IOError:
213 ret = '!!!'
214 return ret
215
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200216 def symbol_plus_offset(self, addr):
217 ret = ''
218 prevsize = 0
219 reladdr = self.subtract_load_addr(addr)
Jerome Forissierae252462018-05-25 15:07:28 +0200220 elf_name = self.elf_for_addr(addr)
221 if elf_name is None:
222 return ''
223 elf = self.get_elf(elf_name)
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200224 cmd = self.arch_prefix('nm')
225 if not reladdr or not elf or not cmd:
226 return ''
Jerome Forissier30999122017-08-25 18:42:58 +0200227 ireladdr = int(reladdr, 16)
Jerome Forissier1cbf7772018-09-07 17:08:23 +0200228 nm = self.my_Popen([cmd, '--numeric-sort', '--print-size', elf])
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200229 for line in iter(nm.stdout.readline, ''):
230 try:
231 addr, size, _, name = line.split()
Jerome Forissier1d8c2a42018-09-07 17:05:21 +0200232 except ValueError:
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200233 # Size is missing
Jerome Forissierb4815422018-06-20 09:43:33 +0200234 try:
235 addr, _, name = line.split()
236 size = '0'
Jerome Forissier1d8c2a42018-09-07 17:05:21 +0200237 except ValueError:
Jerome Forissierb4815422018-06-20 09:43:33 +0200238 # E.g., undefined (external) symbols (line = "U symbol")
239 continue
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200240 iaddr = int(addr, 16)
241 isize = int(size, 16)
242 if iaddr == ireladdr:
243 ret = name
244 break
245 if iaddr < ireladdr and iaddr + isize >= ireladdr:
246 offs = ireladdr - iaddr
247 ret = name + '+' + str(offs)
248 break
249 if iaddr > ireladdr and prevsize == 0:
250 offs = iaddr + ireladdr
251 ret = prevname + '+' + str(offs)
252 break
253 prevsize = size
254 prevname = name
255 nm.terminate()
256 return ret
257
258 def section_plus_offset(self, addr):
259 ret = ''
260 reladdr = self.subtract_load_addr(addr)
Jerome Forissierae252462018-05-25 15:07:28 +0200261 elf_name = self.elf_for_addr(addr)
262 if elf_name is None:
263 return ''
264 elf = self.get_elf(elf_name)
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200265 cmd = self.arch_prefix('objdump')
266 if not reladdr or not elf or not cmd:
267 return ''
Jerome Forissier30999122017-08-25 18:42:58 +0200268 iaddr = int(reladdr, 16)
Jerome Forissier1cbf7772018-09-07 17:08:23 +0200269 objdump = self.my_Popen([cmd, '--section-headers', elf])
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200270 for line in iter(objdump.stdout.readline, ''):
271 try:
272 idx, name, size, vma, lma, offs, algn = line.split()
Jerome Forissier1d8c2a42018-09-07 17:05:21 +0200273 except ValueError:
Jerome Forissierae252462018-05-25 15:07:28 +0200274 continue
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200275 ivma = int(vma, 16)
276 isize = int(size, 16)
277 if ivma == iaddr:
278 ret = name
279 break
280 if ivma < iaddr and ivma + isize >= iaddr:
281 offs = iaddr - ivma
282 ret = name + '+' + str(offs)
283 break
284 objdump.terminate()
285 return ret
286
287 def process_abort(self, line):
288 ret = ''
289 match = re.search(ABORT_ADDR_RE, line)
290 addr = match.group('addr')
291 pre = match.start('addr')
292 post = match.end('addr')
293 sym = self.symbol_plus_offset(addr)
294 sec = self.section_plus_offset(addr)
295 if sym or sec:
296 ret += line[:pre]
297 ret += addr
298 if sym:
299 ret += ' ' + sym
300 if sec:
301 ret += ' ' + sec
302 ret += line[post:]
303 return ret
304
Jerome Forissier30999122017-08-25 18:42:58 +0200305 # Return all ELF sections with the ALLOC flag
Jerome Forissierae252462018-05-25 15:07:28 +0200306 def read_sections(self, elf_name):
307 if elf_name is None:
Jerome Forissier30999122017-08-25 18:42:58 +0200308 return
Jerome Forissierae252462018-05-25 15:07:28 +0200309 if elf_name in self._sections:
310 return
311 elf = self.get_elf(elf_name)
Jerome Forissier30999122017-08-25 18:42:58 +0200312 cmd = self.arch_prefix('objdump')
313 if not elf or not cmd:
314 return
Jerome Forissierae252462018-05-25 15:07:28 +0200315 self._sections[elf_name] = []
Jerome Forissier1cbf7772018-09-07 17:08:23 +0200316 objdump = self.my_Popen([cmd, '--section-headers', elf])
Jerome Forissier30999122017-08-25 18:42:58 +0200317 for line in iter(objdump.stdout.readline, ''):
318 try:
319 _, name, size, vma, _, _, _ = line.split()
Jerome Forissier1d8c2a42018-09-07 17:05:21 +0200320 except ValueError:
Jerome Forissier30999122017-08-25 18:42:58 +0200321 if 'ALLOC' in line:
Jerome Forissierae252462018-05-25 15:07:28 +0200322 self._sections[elf_name].append([name, int(vma, 16),
323 int(size, 16)])
Jerome Forissier30999122017-08-25 18:42:58 +0200324
325 def overlaps(self, section, addr, size):
326 sec_addr = section[1]
327 sec_size = section[2]
328 if not size or not sec_size:
329 return False
Jerome Forissierae252462018-05-25 15:07:28 +0200330 return ((addr <= (sec_addr + sec_size - 1)) and
331 ((addr + size - 1) >= sec_addr))
Jerome Forissier30999122017-08-25 18:42:58 +0200332
Jerome Forissierae252462018-05-25 15:07:28 +0200333 def sections_in_region(self, addr, size, elf_idx):
Jerome Forissier30999122017-08-25 18:42:58 +0200334 ret = ''
335 addr = self.subtract_load_addr(addr)
336 if not addr:
337 return ''
338 iaddr = int(addr, 16)
339 isize = int(size, 16)
Jerome Forissierae252462018-05-25 15:07:28 +0200340 elf = self._elfs[int(elf_idx)][0]
341 if elf is None:
342 return ''
343 self.read_sections(elf)
344 if elf not in self._sections:
345 return ''
346 for s in self._sections[elf]:
Jerome Forissier30999122017-08-25 18:42:58 +0200347 if self.overlaps(s, iaddr, isize):
348 ret += ' ' + s[0]
349 return ret
350
Jerome Forissier733a15f2017-05-19 17:40:17 +0200351 def reset(self):
352 self._call_stack_found = False
Jerome Forissier733a15f2017-05-19 17:40:17 +0200353 if self._addr2line:
354 self._addr2line.terminate()
355 self._addr2line = None
Jerome Forissierae252462018-05-25 15:07:28 +0200356 self._addr2line_elf_name = None
Jerome Forissierd7204312017-09-04 17:58:52 +0200357 self._arch = None
Jerome Forissier142c5cc2017-08-24 15:07:17 +0200358 self._saved_abort_line = ''
Jerome Forissierae252462018-05-25 15:07:28 +0200359 self._sections = {} # {elf_name: [[name, addr, size], ...], ...}
360 self._regions = [] # [[addr, size, elf_idx, saved line], ...]
361 self._elfs = {0: ["tee.elf", 0]} # {idx: [uuid, load_addr], ...}
Sumit Gargc90b6662019-03-28 18:24:21 +0530362 self._func_graph_found = False
363 self._func_graph_skip_line = True
Jerome Forissier733a15f2017-05-19 17:40:17 +0200364
Jerome Forissier095567e2018-05-29 17:42:34 +0200365 def pretty_print_path(self, path):
366 if self._strip_path:
367 return re.sub(re.escape(self._strip_path) + '/*', '', path)
368 return path
369
Jerome Forissier733a15f2017-05-19 17:40:17 +0200370 def write(self, line):
Jerome Forissier6e7c2e92018-11-14 11:02:49 +0100371 if self._call_stack_found:
372 match = re.search(STACK_ADDR_RE, line)
Jerome Forissier30999122017-08-25 18:42:58 +0200373 if match:
374 addr = match.group('addr')
Jerome Forissier6e7c2e92018-11-14 11:02:49 +0100375 pre = match.start('addr')
376 post = match.end('addr')
377 self._out.write(line[:pre])
378 self._out.write(addr)
379 res = self.resolve(addr)
380 res = self.pretty_print_path(res)
381 self._out.write(' ' + res)
382 self._out.write(line[post:])
Jerome Forissierae252462018-05-25 15:07:28 +0200383 return
Jerome Forissier6e7c2e92018-11-14 11:02:49 +0100384 else:
Jerome Forissier27b83ad2017-10-06 13:37:35 +0200385 self.reset()
Sumit Gargc90b6662019-03-28 18:24:21 +0530386 if self._func_graph_found:
387 match = re.search(GRAPH_ADDR_RE, line)
388 match_re = re.search(GRAPH_RE, line)
389 if match:
390 addr = match.group('addr')
391 pre = match.start('addr')
392 post = match.end('addr')
393 self._out.write(line[:pre])
394 res = self.resolve(addr)
395 res_arr = re.split(' ', res)
396 self._out.write(res_arr[0])
397 self._out.write(line[post:])
398 self._func_graph_skip_line = False
399 return
400 elif match_re:
401 self._out.write(line)
402 return
403 elif self._func_graph_skip_line:
404 return
405 else:
406 self.reset()
Jerome Forissier6e7c2e92018-11-14 11:02:49 +0100407 match = re.search(REGION_RE, line)
408 if match:
409 # Region table: save info for later processing once
410 # we know which UUID corresponds to which ELF index
411 addr = match.group('addr')
412 size = match.group('size')
413 elf_idx = match.group('elf_idx')
414 self._regions.append([addr, size, elf_idx, line])
415 return
416 match = re.search(ELF_LIST_RE, line)
417 if match:
418 # ELF list: save info for later. Region table and ELF list
419 # will be displayed when the call stack is reached
420 i = int(match.group('idx'))
421 self._elfs[i] = [match.group('uuid'), match.group('load_addr'),
422 line]
423 return
424 match = re.search(CALL_STACK_RE, line)
425 if match:
426 self._call_stack_found = True
427 if self._regions:
428 for r in self._regions:
429 r_addr = r[0]
430 r_size = r[1]
431 elf_idx = r[2]
432 saved_line = r[3]
433 if elf_idx is None:
434 self._out.write(saved_line)
435 else:
436 self._out.write(saved_line.strip() +
437 self.sections_in_region(r_addr,
438 r_size,
439 elf_idx) +
440 '\n')
441 if self._elfs:
442 for k in self._elfs:
443 e = self._elfs[k]
444 if (len(e) >= 3):
445 # TA executable or library
446 self._out.write(e[2].strip())
447 elf = self.get_elf(e[0])
448 if elf:
449 rpath = os.path.realpath(elf)
450 path = self.pretty_print_path(rpath)
451 self._out.write(' (' + path + ')')
452 self._out.write('\n')
453 # Here is a good place to resolve the abort address because we
454 # have all the information we need
455 if self._saved_abort_line:
456 self._out.write(self.process_abort(self._saved_abort_line))
Sumit Gargc90b6662019-03-28 18:24:21 +0530457 match = re.search(FUNC_GRAPH_RE, line)
458 if match:
459 self._func_graph_found = True
Jerome Forissier6e7c2e92018-11-14 11:02:49 +0100460 match = re.search(ABORT_ADDR_RE, line)
461 if match:
462 self.reset()
463 # At this point the arch and TA load address are unknown.
464 # Save the line so We can translate the abort address later.
465 self._saved_abort_line = line
466 self._out.write(line)
Jerome Forissier733a15f2017-05-19 17:40:17 +0200467
468 def flush(self):
469 self._out.flush()
470
Jerome Forissierae252462018-05-25 15:07:28 +0200471
Jerome Forissier733a15f2017-05-19 17:40:17 +0200472def main():
473 args = get_args()
474 if args.dir:
475 # Flatten list in case -d is used several times *and* with multiple
476 # arguments
477 args.dirs = [item for sublist in args.dir for item in sublist]
478 else:
479 args.dirs = []
480 symbolizer = Symbolizer(sys.stdout, args.dirs, args.strip_path)
481
482 for line in sys.stdin:
483 symbolizer.write(line)
484 symbolizer.flush()
485
Jerome Forissier1d8c2a42018-09-07 17:05:21 +0200486
Jerome Forissier733a15f2017-05-19 17:40:17 +0200487if __name__ == "__main__":
488 main()