15c2c0fb3SJerome Forissier#!/usr/bin/env python3 25c2c0fb3SJerome Forissier# SPDX-License-Identifier: BSD-2-Clause 35c2c0fb3SJerome Forissier# 45c2c0fb3SJerome Forissier# Copyright (c) 2023, Linaro Limited 55c2c0fb3SJerome Forissier# 65c2c0fb3SJerome Forissier# Converts a ftrace binary file to text. The input file has the following 75c2c0fb3SJerome Forissier# format: 85c2c0fb3SJerome Forissier# 95c2c0fb3SJerome Forissier# <ASCII text> <zero or more nul bytes> FTRACE\x00\x01 <binary data>... 105c2c0fb3SJerome Forissier# 115c2c0fb3SJerome Forissier# <binary data> is an array of 64-bit integers. 125c2c0fb3SJerome Forissier# - When the topmost byte is 0, the entry indicates a function return and the 135c2c0fb3SJerome Forissier# remaining bytes are a duration in nanoseconds. 145c2c0fb3SJerome Forissier# - A non-zero value is a stack depth, indicating a function entry, and the 155c2c0fb3SJerome Forissier# remaining bytes are the function's address. 165c2c0fb3SJerome Forissier 175c2c0fb3SJerome Forissierimport sys 185c2c0fb3SJerome Forissier 195c2c0fb3SJerome Forissier 205c2c0fb3SJerome Forissierline = "" 215c2c0fb3SJerome Forissiercurr_depth = 0 225c2c0fb3SJerome Forissier 235c2c0fb3SJerome Forissier 245c2c0fb3SJerome Forissierdef usage(): 255c2c0fb3SJerome Forissier print(f"Usage: {sys.argv[0]} ftrace.out") 265c2c0fb3SJerome Forissier print("Converts a ftrace file to text. Output is written to stdout.") 275c2c0fb3SJerome Forissier sys.exit(0) 285c2c0fb3SJerome Forissier 295c2c0fb3SJerome Forissier 305c2c0fb3SJerome Forissierdef format_time(ns): 315c2c0fb3SJerome Forissier if ns < 1000000: 325c2c0fb3SJerome Forissier us = ns / 1000 335c2c0fb3SJerome Forissier return f"{us:7.3f} us" 34*af3fb624SJerome Forissier elif ns < 1000000000: 355c2c0fb3SJerome Forissier ms = ns / 1000000 365c2c0fb3SJerome Forissier return f"{ms:7.3f} ms" 37*af3fb624SJerome Forissier else: 38*af3fb624SJerome Forissier s = ns / 1000000000 39*af3fb624SJerome Forissier return f"{s:7.3f} s " 405c2c0fb3SJerome Forissier 415c2c0fb3SJerome Forissier 425c2c0fb3SJerome Forissierdef display(depth, val): 435c2c0fb3SJerome Forissier global line, curr_depth 445c2c0fb3SJerome Forissier if depth != 0: 455c2c0fb3SJerome Forissier curr_depth = depth 465c2c0fb3SJerome Forissier if line != "": 475c2c0fb3SJerome Forissier line = line.replace("TIME", " " * 10) + " {" 485c2c0fb3SJerome Forissier print(line) 495c2c0fb3SJerome Forissier line = "" 505c2c0fb3SJerome Forissier line = f" TIME | {depth:3} | " + " " * depth + f"0x{val:016x}()" 515c2c0fb3SJerome Forissier else: 525c2c0fb3SJerome Forissier if line != "": 535c2c0fb3SJerome Forissier line = line.replace("TIME", format_time(val)) 545c2c0fb3SJerome Forissier print(line) 555c2c0fb3SJerome Forissier line = "" 565c2c0fb3SJerome Forissier else: 575c2c0fb3SJerome Forissier if curr_depth != 0: 585c2c0fb3SJerome Forissier curr_depth = curr_depth - 1 595c2c0fb3SJerome Forissier print(" " + format_time(val) + f" | {curr_depth:3} | " + 605c2c0fb3SJerome Forissier " " * curr_depth + "}") 615c2c0fb3SJerome Forissier 625c2c0fb3SJerome Forissier 635c2c0fb3SJerome Forissierdef main(): 645c2c0fb3SJerome Forissier if len(sys.argv) < 2: 655c2c0fb3SJerome Forissier usage() 665c2c0fb3SJerome Forissier with open(sys.argv[1], 'rb') as f: 675c2c0fb3SJerome Forissier s = f.read() 685c2c0fb3SJerome Forissier magic = s.find(b'FTRACE\x00\x01') 695c2c0fb3SJerome Forissier if magic == -1: 705c2c0fb3SJerome Forissier print("Magic not found", file=sys.stderr) 715c2c0fb3SJerome Forissier sys.exit(1) 725c2c0fb3SJerome Forissier print(s[:magic].rstrip(b'\x00').decode()) 735c2c0fb3SJerome Forissier s = s[magic + 8:] 745c2c0fb3SJerome Forissier for i in range(0, len(s), 8): 755c2c0fb3SJerome Forissier elem = int.from_bytes(s[i:i + 8], byteorder="little", signed=False) 765c2c0fb3SJerome Forissier depth = elem >> 56 775c2c0fb3SJerome Forissier val = elem & 0xFFFFFFFFFFFFFF 785c2c0fb3SJerome Forissier display(depth, val) 795c2c0fb3SJerome Forissier 805c2c0fb3SJerome Forissier 815c2c0fb3SJerome Forissierif __name__ == "__main__": 825c2c0fb3SJerome Forissier main() 83