1733a15f2SJerome Forissier#!/usr/bin/env python 21bb92983SJerome Forissier# SPDX-License-Identifier: BSD-2-Clause 3733a15f2SJerome Forissier# 4733a15f2SJerome Forissier# Copyright (c) 2017, Linaro Limited 5733a15f2SJerome Forissier# 6733a15f2SJerome Forissier 7733a15f2SJerome Forissier 8733a15f2SJerome Forissierimport argparse 9733a15f2SJerome Forissierimport glob 10157e6213SJerome Forissierimport os 11733a15f2SJerome Forissierimport re 12733a15f2SJerome Forissierimport subprocess 13733a15f2SJerome Forissierimport sys 14733a15f2SJerome Forissier 15733a15f2SJerome ForissierCALL_STACK_RE = re.compile('Call stack:') 16a2b984bdSJoakim Bech# This gets the address from lines looking like this: 17a2b984bdSJoakim Bech# E/TC:0 0x001044a8 186e7c2e91SJerome ForissierSTACK_ADDR_RE = re.compile( 19*b6bc49caSSumit Garg r'[UEIDFM]/T[AC]:(\?+|[0-9]+) [0-9]* +(?P<addr>0x[0-9a-f]+)') 206e7c2e91SJerome ForissierABORT_ADDR_RE = re.compile(r'-abort at address (?P<addr>0x[0-9a-f]+)') 216e7c2e91SJerome ForissierREGION_RE = re.compile(r'region [0-9]+: va (?P<addr>0x[0-9a-f]+) ' 226e7c2e91SJerome Forissier r'pa 0x[0-9a-f]+ size (?P<size>0x[0-9a-f]+)' 236e7c2e91SJerome Forissier r'( flags .{6} (\[(?P<elf_idx>[0-9]+)\])?)?') 24ae252462SJerome ForissierELF_LIST_RE = re.compile(r'\[(?P<idx>[0-9]+)\] (?P<uuid>[0-9a-f\-]+)' 256e7c2e91SJerome Forissier r' @ (?P<load_addr>0x[0-9a-f\-]+)') 26733a15f2SJerome Forissier 27733a15f2SJerome Forissierepilog = ''' 280c5bedb5SJerome ForissierThis scripts reads an OP-TEE abort or panic message from stdin and adds debug 290c5bedb5SJerome Forissierinformation to the output, such as '<function> at <file>:<line>' next to each 300c5bedb5SJerome Forissieraddress in the call stack. Any message generated by OP-TEE and containing a 310c5bedb5SJerome Forissiercall stack can in principle be processed by this script. This currently 320c5bedb5SJerome Forissierincludes aborts and panics from the TEE core as well as from any TA. 330c5bedb5SJerome ForissierThe paths provided on the command line are used to locate the appropriate ELF 340c5bedb5SJerome Forissierbinary (tee.elf or Trusted Application). The GNU binutils (addr2line, objdump, 35f9089765SJerome Forissiernm) are used to extract the debug info. If the CROSS_COMPILE environment 36f9089765SJerome Forissiervariable is set, it is used as a prefix to the binutils tools. That is, the 37f9089765SJerome Forissierscript will invoke $(CROSS_COMPILE)addr2line etc. If it is not set however, 38f9089765SJerome Forissierthe prefix will be determined automatically for each ELF file based on its 39f9089765SJerome Forissierarchitecture (arm-linux-gnueabihf-, aarch64-linux-gnu-). The resulting command 40f9089765SJerome Forissieris then expected to be found in the user's PATH. 41733a15f2SJerome Forissier 420c5bedb5SJerome ForissierOP-TEE abort and panic messages are sent to the secure console. They look like 430c5bedb5SJerome Forissierthe following: 44733a15f2SJerome Forissier 450c5bedb5SJerome Forissier E/TC:0 User TA data-abort at address 0xffffdecd (alignment fault) 46733a15f2SJerome Forissier ... 470c5bedb5SJerome Forissier E/TC:0 Call stack: 480c5bedb5SJerome Forissier E/TC:0 0x4000549e 490c5bedb5SJerome Forissier E/TC:0 0x40001f4b 500c5bedb5SJerome Forissier E/TC:0 0x4000273f 510c5bedb5SJerome Forissier E/TC:0 0x40005da7 52733a15f2SJerome Forissier 53733a15f2SJerome ForissierInspired by a script of the same name by the Chromium project. 54733a15f2SJerome Forissier 55733a15f2SJerome ForissierSample usage: 56733a15f2SJerome Forissier 57733a15f2SJerome Forissier $ scripts/symbolize.py -d out/arm-plat-hikey/core -d ../optee_test/out/ta/* 58733a15f2SJerome Forissier <paste whole dump here> 59733a15f2SJerome Forissier ^D 60733a15f2SJerome Forissier''' 61733a15f2SJerome Forissier 62ae252462SJerome Forissier 63733a15f2SJerome Forissierdef get_args(): 64733a15f2SJerome Forissier parser = argparse.ArgumentParser( 65733a15f2SJerome Forissier formatter_class=argparse.RawDescriptionHelpFormatter, 66733a15f2SJerome Forissier description='Symbolizes OP-TEE abort dumps', 67733a15f2SJerome Forissier epilog=epilog) 68733a15f2SJerome Forissier parser.add_argument('-d', '--dir', action='append', nargs='+', 691d8c2a48SJerome Forissier help='Search for ELF file in DIR. tee.elf is needed ' 701d8c2a48SJerome Forissier 'to decode a TEE Core or pseudo-TA abort, while ' 711d8c2a48SJerome Forissier '<TA_uuid>.elf is required if a user-mode TA has ' 721d8c2a48SJerome Forissier 'crashed. For convenience, ELF files may also be ' 731d8c2a48SJerome Forissier 'given.') 745f7df507SJerome Forissier parser.add_argument('-s', '--strip_path', nargs='?', 751d8c2a48SJerome Forissier help='Strip STRIP_PATH from file paths (default: ' 761d8c2a48SJerome Forissier 'current directory, use -s with no argument to show ' 771d8c2a48SJerome Forissier 'full paths)', default=os.getcwd()) 78733a15f2SJerome Forissier 79733a15f2SJerome Forissier return parser.parse_args() 80733a15f2SJerome Forissier 81ae252462SJerome Forissier 82733a15f2SJerome Forissierclass Symbolizer(object): 83733a15f2SJerome Forissier def __init__(self, out, dirs, strip_path): 84733a15f2SJerome Forissier self._out = out 85733a15f2SJerome Forissier self._dirs = dirs 86733a15f2SJerome Forissier self._strip_path = strip_path 87733a15f2SJerome Forissier self._addr2line = None 88733a15f2SJerome Forissier self.reset() 89733a15f2SJerome Forissier 901cbf777bSJerome Forissier def my_Popen(self, cmd): 911cbf777bSJerome Forissier try: 921cbf777bSJerome Forissier return subprocess.Popen(cmd, stdin=subprocess.PIPE, 931cbf777bSJerome Forissier stdout=subprocess.PIPE) 941cbf777bSJerome Forissier except OSError as e: 951cbf777bSJerome Forissier if e.errno == os.errno.ENOENT: 961cbf777bSJerome Forissier print >> sys.stderr, "*** Error:", cmd[0] + \ 971cbf777bSJerome Forissier ": command not found" 981cbf777bSJerome Forissier sys.exit(1) 991cbf777bSJerome Forissier 100733a15f2SJerome Forissier def get_elf(self, elf_or_uuid): 101733a15f2SJerome Forissier if not elf_or_uuid.endswith('.elf'): 102733a15f2SJerome Forissier elf_or_uuid += '.elf' 103733a15f2SJerome Forissier for d in self._dirs: 104157e6213SJerome Forissier if d.endswith(elf_or_uuid) and os.path.isfile(d): 105157e6213SJerome Forissier return d 106733a15f2SJerome Forissier elf = glob.glob(d + '/' + elf_or_uuid) 107733a15f2SJerome Forissier if elf: 108733a15f2SJerome Forissier return elf[0] 109733a15f2SJerome Forissier 110d720431cSJerome Forissier def set_arch(self): 111d720431cSJerome Forissier if self._arch: 112d720431cSJerome Forissier return 1136e7c2e91SJerome Forissier self._arch = os.getenv('CROSS_COMPILE') 1148a6d4a8bSEtienne Carriere if self._arch: 1158a6d4a8bSEtienne Carriere return 116ae252462SJerome Forissier elf = self.get_elf(self._elfs[0][0]) 117ae252462SJerome Forissier if elf is None: 118ae252462SJerome Forissier return 119ae252462SJerome Forissier p = subprocess.Popen(['file', self.get_elf(self._elfs[0][0])], 120d720431cSJerome Forissier stdout=subprocess.PIPE) 121d720431cSJerome Forissier output = p.stdout.readlines() 122d720431cSJerome Forissier p.terminate() 123d720431cSJerome Forissier if 'ARM aarch64,' in output[0]: 124d720431cSJerome Forissier self._arch = 'aarch64-linux-gnu-' 125d720431cSJerome Forissier elif 'ARM,' in output[0]: 126d720431cSJerome Forissier self._arch = 'arm-linux-gnueabihf-' 127d720431cSJerome Forissier 128142c5cccSJerome Forissier def arch_prefix(self, cmd): 129d720431cSJerome Forissier self.set_arch() 130ae252462SJerome Forissier if self._arch is None: 131ae252462SJerome Forissier return '' 132d720431cSJerome Forissier return self._arch + cmd 133142c5cccSJerome Forissier 134ae252462SJerome Forissier def spawn_addr2line(self, elf_name): 135ae252462SJerome Forissier if elf_name is None: 136ae252462SJerome Forissier return 137ae252462SJerome Forissier if self._addr2line_elf_name is elf_name: 138ae252462SJerome Forissier return 139ae252462SJerome Forissier if self._addr2line: 140ae252462SJerome Forissier self._addr2line.terminate 141ae252462SJerome Forissier self._addr2line = None 142ae252462SJerome Forissier elf = self.get_elf(elf_name) 143733a15f2SJerome Forissier if not elf: 144733a15f2SJerome Forissier return 145142c5cccSJerome Forissier cmd = self.arch_prefix('addr2line') 146142c5cccSJerome Forissier if not cmd: 147733a15f2SJerome Forissier return 1481cbf777bSJerome Forissier self._addr2line = self.my_Popen([cmd, '-f', '-p', '-e', elf]) 149ae252462SJerome Forissier self._addr2line_elf_name = elf_name 150ae252462SJerome Forissier 151ae252462SJerome Forissier # If addr falls into a region that maps a TA ELF file, return the load 152ae252462SJerome Forissier # address of that file. 153ae252462SJerome Forissier def elf_load_addr(self, addr): 154ae252462SJerome Forissier if self._regions: 155ae252462SJerome Forissier for r in self._regions: 156ae252462SJerome Forissier r_addr = int(r[0], 16) 157ae252462SJerome Forissier r_size = int(r[1], 16) 158ae252462SJerome Forissier i_addr = int(addr, 16) 159ae252462SJerome Forissier if (i_addr >= r_addr and i_addr < (r_addr + r_size)): 160ae252462SJerome Forissier # Found region 161ae252462SJerome Forissier elf_idx = r[2] 162ae252462SJerome Forissier if elf_idx is not None: 163ae252462SJerome Forissier return self._elfs[int(elf_idx)][1] 164ae252462SJerome Forissier return None 165ae252462SJerome Forissier else: 166ae252462SJerome Forissier # tee.elf 167ae252462SJerome Forissier return '0x0' 168ae252462SJerome Forissier 169ae252462SJerome Forissier def elf_for_addr(self, addr): 170ae252462SJerome Forissier l_addr = self.elf_load_addr(addr) 171ae252462SJerome Forissier if l_addr is None: 172ae252462SJerome Forissier return None 173ae252462SJerome Forissier if l_addr is '0x0': 174ae252462SJerome Forissier return 'tee.elf' 175ae252462SJerome Forissier for k in self._elfs: 176ae252462SJerome Forissier e = self._elfs[k] 177ae252462SJerome Forissier if int(e[1], 16) == int(l_addr, 16): 178ae252462SJerome Forissier return e[0] 179ae252462SJerome Forissier return None 180733a15f2SJerome Forissier 181142c5cccSJerome Forissier def subtract_load_addr(self, addr): 182ae252462SJerome Forissier l_addr = self.elf_load_addr(addr) 183ae252462SJerome Forissier if l_addr is None: 184ae252462SJerome Forissier return None 185ae252462SJerome Forissier if int(l_addr, 16) > int(addr, 16): 186142c5cccSJerome Forissier return '' 187ae252462SJerome Forissier return '0x{:x}'.format(int(addr, 16) - int(l_addr, 16)) 188142c5cccSJerome Forissier 189142c5cccSJerome Forissier def resolve(self, addr): 190142c5cccSJerome Forissier reladdr = self.subtract_load_addr(addr) 191ae252462SJerome Forissier self.spawn_addr2line(self.elf_for_addr(addr)) 192142c5cccSJerome Forissier if not reladdr or not self._addr2line: 193733a15f2SJerome Forissier return '???' 194733a15f2SJerome Forissier try: 195733a15f2SJerome Forissier print >> self._addr2line.stdin, reladdr 196733a15f2SJerome Forissier ret = self._addr2line.stdout.readline().rstrip('\n') 197733a15f2SJerome Forissier except IOError: 198733a15f2SJerome Forissier ret = '!!!' 199733a15f2SJerome Forissier return ret 200733a15f2SJerome Forissier 201142c5cccSJerome Forissier def symbol_plus_offset(self, addr): 202142c5cccSJerome Forissier ret = '' 203142c5cccSJerome Forissier prevsize = 0 204142c5cccSJerome Forissier reladdr = self.subtract_load_addr(addr) 205ae252462SJerome Forissier elf_name = self.elf_for_addr(addr) 206ae252462SJerome Forissier if elf_name is None: 207ae252462SJerome Forissier return '' 208ae252462SJerome Forissier elf = self.get_elf(elf_name) 209142c5cccSJerome Forissier cmd = self.arch_prefix('nm') 210142c5cccSJerome Forissier if not reladdr or not elf or not cmd: 211142c5cccSJerome Forissier return '' 21230999126SJerome Forissier ireladdr = int(reladdr, 16) 2131cbf777bSJerome Forissier nm = self.my_Popen([cmd, '--numeric-sort', '--print-size', elf]) 214142c5cccSJerome Forissier for line in iter(nm.stdout.readline, ''): 215142c5cccSJerome Forissier try: 216142c5cccSJerome Forissier addr, size, _, name = line.split() 2171d8c2a48SJerome Forissier except ValueError: 218142c5cccSJerome Forissier # Size is missing 219b4815427SJerome Forissier try: 220142c5cccSJerome Forissier addr, _, name = line.split() 221142c5cccSJerome Forissier size = '0' 2221d8c2a48SJerome Forissier except ValueError: 223b4815427SJerome Forissier # E.g., undefined (external) symbols (line = "U symbol") 224b4815427SJerome Forissier continue 225142c5cccSJerome Forissier iaddr = int(addr, 16) 226142c5cccSJerome Forissier isize = int(size, 16) 227142c5cccSJerome Forissier if iaddr == ireladdr: 228142c5cccSJerome Forissier ret = name 229142c5cccSJerome Forissier break 230142c5cccSJerome Forissier if iaddr < ireladdr and iaddr + isize >= ireladdr: 231142c5cccSJerome Forissier offs = ireladdr - iaddr 232142c5cccSJerome Forissier ret = name + '+' + str(offs) 233142c5cccSJerome Forissier break 234142c5cccSJerome Forissier if iaddr > ireladdr and prevsize == 0: 235142c5cccSJerome Forissier offs = iaddr + ireladdr 236142c5cccSJerome Forissier ret = prevname + '+' + str(offs) 237142c5cccSJerome Forissier break 238142c5cccSJerome Forissier prevsize = size 239142c5cccSJerome Forissier prevname = name 240142c5cccSJerome Forissier nm.terminate() 241142c5cccSJerome Forissier return ret 242142c5cccSJerome Forissier 243142c5cccSJerome Forissier def section_plus_offset(self, addr): 244142c5cccSJerome Forissier ret = '' 245142c5cccSJerome Forissier reladdr = self.subtract_load_addr(addr) 246ae252462SJerome Forissier elf_name = self.elf_for_addr(addr) 247ae252462SJerome Forissier if elf_name is None: 248ae252462SJerome Forissier return '' 249ae252462SJerome Forissier elf = self.get_elf(elf_name) 250142c5cccSJerome Forissier cmd = self.arch_prefix('objdump') 251142c5cccSJerome Forissier if not reladdr or not elf or not cmd: 252142c5cccSJerome Forissier return '' 25330999126SJerome Forissier iaddr = int(reladdr, 16) 2541cbf777bSJerome Forissier objdump = self.my_Popen([cmd, '--section-headers', elf]) 255142c5cccSJerome Forissier for line in iter(objdump.stdout.readline, ''): 256142c5cccSJerome Forissier try: 257142c5cccSJerome Forissier idx, name, size, vma, lma, offs, algn = line.split() 2581d8c2a48SJerome Forissier except ValueError: 259ae252462SJerome Forissier continue 260142c5cccSJerome Forissier ivma = int(vma, 16) 261142c5cccSJerome Forissier isize = int(size, 16) 262142c5cccSJerome Forissier if ivma == iaddr: 263142c5cccSJerome Forissier ret = name 264142c5cccSJerome Forissier break 265142c5cccSJerome Forissier if ivma < iaddr and ivma + isize >= iaddr: 266142c5cccSJerome Forissier offs = iaddr - ivma 267142c5cccSJerome Forissier ret = name + '+' + str(offs) 268142c5cccSJerome Forissier break 269142c5cccSJerome Forissier objdump.terminate() 270142c5cccSJerome Forissier return ret 271142c5cccSJerome Forissier 272142c5cccSJerome Forissier def process_abort(self, line): 273142c5cccSJerome Forissier ret = '' 274142c5cccSJerome Forissier match = re.search(ABORT_ADDR_RE, line) 275142c5cccSJerome Forissier addr = match.group('addr') 276142c5cccSJerome Forissier pre = match.start('addr') 277142c5cccSJerome Forissier post = match.end('addr') 278142c5cccSJerome Forissier sym = self.symbol_plus_offset(addr) 279142c5cccSJerome Forissier sec = self.section_plus_offset(addr) 280142c5cccSJerome Forissier if sym or sec: 281142c5cccSJerome Forissier ret += line[:pre] 282142c5cccSJerome Forissier ret += addr 283142c5cccSJerome Forissier if sym: 284142c5cccSJerome Forissier ret += ' ' + sym 285142c5cccSJerome Forissier if sec: 286142c5cccSJerome Forissier ret += ' ' + sec 287142c5cccSJerome Forissier ret += line[post:] 288142c5cccSJerome Forissier return ret 289142c5cccSJerome Forissier 29030999126SJerome Forissier # Return all ELF sections with the ALLOC flag 291ae252462SJerome Forissier def read_sections(self, elf_name): 292ae252462SJerome Forissier if elf_name is None: 29330999126SJerome Forissier return 294ae252462SJerome Forissier if elf_name in self._sections: 295ae252462SJerome Forissier return 296ae252462SJerome Forissier elf = self.get_elf(elf_name) 29730999126SJerome Forissier cmd = self.arch_prefix('objdump') 29830999126SJerome Forissier if not elf or not cmd: 29930999126SJerome Forissier return 300ae252462SJerome Forissier self._sections[elf_name] = [] 3011cbf777bSJerome Forissier objdump = self.my_Popen([cmd, '--section-headers', elf]) 30230999126SJerome Forissier for line in iter(objdump.stdout.readline, ''): 30330999126SJerome Forissier try: 30430999126SJerome Forissier _, name, size, vma, _, _, _ = line.split() 3051d8c2a48SJerome Forissier except ValueError: 30630999126SJerome Forissier if 'ALLOC' in line: 307ae252462SJerome Forissier self._sections[elf_name].append([name, int(vma, 16), 308ae252462SJerome Forissier int(size, 16)]) 30930999126SJerome Forissier 31030999126SJerome Forissier def overlaps(self, section, addr, size): 31130999126SJerome Forissier sec_addr = section[1] 31230999126SJerome Forissier sec_size = section[2] 31330999126SJerome Forissier if not size or not sec_size: 31430999126SJerome Forissier return False 315ae252462SJerome Forissier return ((addr <= (sec_addr + sec_size - 1)) and 316ae252462SJerome Forissier ((addr + size - 1) >= sec_addr)) 31730999126SJerome Forissier 318ae252462SJerome Forissier def sections_in_region(self, addr, size, elf_idx): 31930999126SJerome Forissier ret = '' 32030999126SJerome Forissier addr = self.subtract_load_addr(addr) 32130999126SJerome Forissier if not addr: 32230999126SJerome Forissier return '' 32330999126SJerome Forissier iaddr = int(addr, 16) 32430999126SJerome Forissier isize = int(size, 16) 325ae252462SJerome Forissier elf = self._elfs[int(elf_idx)][0] 326ae252462SJerome Forissier if elf is None: 327ae252462SJerome Forissier return '' 328ae252462SJerome Forissier self.read_sections(elf) 329ae252462SJerome Forissier if elf not in self._sections: 330ae252462SJerome Forissier return '' 331ae252462SJerome Forissier for s in self._sections[elf]: 33230999126SJerome Forissier if self.overlaps(s, iaddr, isize): 33330999126SJerome Forissier ret += ' ' + s[0] 33430999126SJerome Forissier return ret 33530999126SJerome Forissier 336733a15f2SJerome Forissier def reset(self): 337733a15f2SJerome Forissier self._call_stack_found = False 338733a15f2SJerome Forissier if self._addr2line: 339733a15f2SJerome Forissier self._addr2line.terminate() 340733a15f2SJerome Forissier self._addr2line = None 341ae252462SJerome Forissier self._addr2line_elf_name = None 342d720431cSJerome Forissier self._arch = None 343142c5cccSJerome Forissier self._saved_abort_line = '' 344ae252462SJerome Forissier self._sections = {} # {elf_name: [[name, addr, size], ...], ...} 345ae252462SJerome Forissier self._regions = [] # [[addr, size, elf_idx, saved line], ...] 346ae252462SJerome Forissier self._elfs = {0: ["tee.elf", 0]} # {idx: [uuid, load_addr], ...} 347733a15f2SJerome Forissier 348095567e5SJerome Forissier def pretty_print_path(self, path): 349095567e5SJerome Forissier if self._strip_path: 350095567e5SJerome Forissier return re.sub(re.escape(self._strip_path) + '/*', '', path) 351095567e5SJerome Forissier return path 352095567e5SJerome Forissier 353733a15f2SJerome Forissier def write(self, line): 354733a15f2SJerome Forissier if self._call_stack_found: 355733a15f2SJerome Forissier match = re.search(STACK_ADDR_RE, line) 356733a15f2SJerome Forissier if match: 357733a15f2SJerome Forissier addr = match.group('addr') 358733a15f2SJerome Forissier pre = match.start('addr') 359733a15f2SJerome Forissier post = match.end('addr') 360733a15f2SJerome Forissier self._out.write(line[:pre]) 361733a15f2SJerome Forissier self._out.write(addr) 362733a15f2SJerome Forissier res = self.resolve(addr) 363095567e5SJerome Forissier res = self.pretty_print_path(res) 364733a15f2SJerome Forissier self._out.write(' ' + res) 365733a15f2SJerome Forissier self._out.write(line[post:]) 366733a15f2SJerome Forissier return 367733a15f2SJerome Forissier else: 368733a15f2SJerome Forissier self.reset() 36930999126SJerome Forissier match = re.search(REGION_RE, line) 37030999126SJerome Forissier if match: 371ae252462SJerome Forissier # Region table: save info for later processing once 372ae252462SJerome Forissier # we know which UUID corresponds to which ELF index 37330999126SJerome Forissier addr = match.group('addr') 37430999126SJerome Forissier size = match.group('size') 375ae252462SJerome Forissier elf_idx = match.group('elf_idx') 376ae252462SJerome Forissier self._regions.append([addr, size, elf_idx, line]) 377ae252462SJerome Forissier return 378ae252462SJerome Forissier match = re.search(ELF_LIST_RE, line) 379ae252462SJerome Forissier if match: 380ae252462SJerome Forissier # ELF list: save info for later. Region table and ELF list 381ae252462SJerome Forissier # will be displayed when the call stack is reached 382ae252462SJerome Forissier i = int(match.group('idx')) 383ae252462SJerome Forissier self._elfs[i] = [match.group('uuid'), match.group('load_addr'), 384ae252462SJerome Forissier line] 38530999126SJerome Forissier return 386733a15f2SJerome Forissier match = re.search(CALL_STACK_RE, line) 387733a15f2SJerome Forissier if match: 388733a15f2SJerome Forissier self._call_stack_found = True 389ae252462SJerome Forissier if self._regions: 390ae252462SJerome Forissier for r in self._regions: 391ae252462SJerome Forissier r_addr = r[0] 392ae252462SJerome Forissier r_size = r[1] 393ae252462SJerome Forissier elf_idx = r[2] 394ae252462SJerome Forissier saved_line = r[3] 395ae252462SJerome Forissier if elf_idx is None: 396ae252462SJerome Forissier self._out.write(saved_line) 397ae252462SJerome Forissier else: 398ae252462SJerome Forissier self._out.write(saved_line.strip() + 399ae252462SJerome Forissier self.sections_in_region(r_addr, 400ae252462SJerome Forissier r_size, 401ae252462SJerome Forissier elf_idx) + 402ae252462SJerome Forissier '\n') 403ae252462SJerome Forissier if self._elfs: 404ae252462SJerome Forissier for k in self._elfs: 405ae252462SJerome Forissier e = self._elfs[k] 406ae252462SJerome Forissier if (len(e) >= 3): 4071e6f2ea0SJerome Forissier # TA executable or library 408095567e5SJerome Forissier self._out.write(e[2].strip()) 409095567e5SJerome Forissier elf = self.get_elf(e[0]) 410095567e5SJerome Forissier if elf: 411095567e5SJerome Forissier rpath = os.path.realpath(elf) 412095567e5SJerome Forissier path = self.pretty_print_path(rpath) 413095567e5SJerome Forissier self._out.write(' (' + path + ')') 414095567e5SJerome Forissier self._out.write('\n') 415142c5cccSJerome Forissier # Here is a good place to resolve the abort address because we 416142c5cccSJerome Forissier # have all the information we need 417142c5cccSJerome Forissier if self._saved_abort_line: 418142c5cccSJerome Forissier self._out.write(self.process_abort(self._saved_abort_line)) 419142c5cccSJerome Forissier match = re.search(ABORT_ADDR_RE, line) 420142c5cccSJerome Forissier if match: 42127b83ad2SJerome Forissier self.reset() 422142c5cccSJerome Forissier # At this point the arch and TA load address are unknown. 423142c5cccSJerome Forissier # Save the line so We can translate the abort address later. 424142c5cccSJerome Forissier self._saved_abort_line = line 425733a15f2SJerome Forissier self._out.write(line) 426733a15f2SJerome Forissier 427733a15f2SJerome Forissier def flush(self): 428733a15f2SJerome Forissier self._out.flush() 429733a15f2SJerome Forissier 430ae252462SJerome Forissier 431733a15f2SJerome Forissierdef main(): 432733a15f2SJerome Forissier args = get_args() 433733a15f2SJerome Forissier if args.dir: 434733a15f2SJerome Forissier # Flatten list in case -d is used several times *and* with multiple 435733a15f2SJerome Forissier # arguments 436733a15f2SJerome Forissier args.dirs = [item for sublist in args.dir for item in sublist] 437733a15f2SJerome Forissier else: 438733a15f2SJerome Forissier args.dirs = [] 439733a15f2SJerome Forissier symbolizer = Symbolizer(sys.stdout, args.dirs, args.strip_path) 440733a15f2SJerome Forissier 441733a15f2SJerome Forissier for line in sys.stdin: 442733a15f2SJerome Forissier symbolizer.write(line) 443733a15f2SJerome Forissier symbolizer.flush() 444733a15f2SJerome Forissier 4451d8c2a48SJerome Forissier 446733a15f2SJerome Forissierif __name__ == "__main__": 447733a15f2SJerome Forissier main() 448