1cc1dc7a3Sopenharmony_ci#!/usr/bin/env python3 2cc1dc7a3Sopenharmony_ci# SPDX-License-Identifier: Apache-2.0 3cc1dc7a3Sopenharmony_ci# ----------------------------------------------------------------------------- 4cc1dc7a3Sopenharmony_ci# Copyright 2021-2022 Arm Limited 5cc1dc7a3Sopenharmony_ci# 6cc1dc7a3Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); you may not 7cc1dc7a3Sopenharmony_ci# use this file except in compliance with the License. You may obtain a copy 8cc1dc7a3Sopenharmony_ci# of the License at: 9cc1dc7a3Sopenharmony_ci# 10cc1dc7a3Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 11cc1dc7a3Sopenharmony_ci# 12cc1dc7a3Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 13cc1dc7a3Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14cc1dc7a3Sopenharmony_ci# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15cc1dc7a3Sopenharmony_ci# License for the specific language governing permissions and limitations 16cc1dc7a3Sopenharmony_ci# under the License. 17cc1dc7a3Sopenharmony_ci# ----------------------------------------------------------------------------- 18cc1dc7a3Sopenharmony_ci""" 19cc1dc7a3Sopenharmony_ciThe ``astc_dump_binary`` utility provides a wrapper around the ``objdump`` 20cc1dc7a3Sopenharmony_ciutility to extract disassembly of specific functions. Currently only matches 21cc1dc7a3Sopenharmony_cithe root name, for sake of command line sanity, so all overloads get dumped. 22cc1dc7a3Sopenharmony_ci 23cc1dc7a3Sopenharmony_ciUsing __attribute__((noinline)) can be useful during profiling to stop any 24cc1dc7a3Sopenharmony_cifunctions of interest getting inlined once they get too small ... 25cc1dc7a3Sopenharmony_ci""" 26cc1dc7a3Sopenharmony_ci 27cc1dc7a3Sopenharmony_ci 28cc1dc7a3Sopenharmony_ciimport argparse 29cc1dc7a3Sopenharmony_ciimport re 30cc1dc7a3Sopenharmony_ciimport shutil 31cc1dc7a3Sopenharmony_ciimport subprocess as sp 32cc1dc7a3Sopenharmony_ciimport sys 33cc1dc7a3Sopenharmony_ci 34cc1dc7a3Sopenharmony_ci 35cc1dc7a3Sopenharmony_cidef run_objdump(binary, symbol): 36cc1dc7a3Sopenharmony_ci """ 37cc1dc7a3Sopenharmony_ci Run objdump on a single binary and extract the range for a given symbol. 38cc1dc7a3Sopenharmony_ci 39cc1dc7a3Sopenharmony_ci Output is printed to stdout. 40cc1dc7a3Sopenharmony_ci 41cc1dc7a3Sopenharmony_ci Args: 42cc1dc7a3Sopenharmony_ci binary (str): The path of the binary file to process. 43cc1dc7a3Sopenharmony_ci symbol (str): The symbol to match. 44cc1dc7a3Sopenharmony_ci 45cc1dc7a3Sopenharmony_ci Raises: 46cc1dc7a3Sopenharmony_ci CalledProcessException: The ``objdump`` subprocess failed for any reason. 47cc1dc7a3Sopenharmony_ci """ 48cc1dc7a3Sopenharmony_ci args = [ 49cc1dc7a3Sopenharmony_ci "objdump", "-C", 50cc1dc7a3Sopenharmony_ci "-M", "intel", 51cc1dc7a3Sopenharmony_ci "--no-show-raw", 52cc1dc7a3Sopenharmony_ci "-d", "-S", 53cc1dc7a3Sopenharmony_ci binary 54cc1dc7a3Sopenharmony_ci ] 55cc1dc7a3Sopenharmony_ci 56cc1dc7a3Sopenharmony_ci result = sp.run(args, stdout=sp.PIPE, stderr=sp.PIPE, 57cc1dc7a3Sopenharmony_ci check=True, universal_newlines=True) 58cc1dc7a3Sopenharmony_ci 59cc1dc7a3Sopenharmony_ci funcPattern = re.compile(r"^[0-9a-f]{16} <(.*?)\(.*\)>:$") 60cc1dc7a3Sopenharmony_ci 61cc1dc7a3Sopenharmony_ci funcLines = [] 62cc1dc7a3Sopenharmony_ci funcActive = False 63cc1dc7a3Sopenharmony_ci lines = result.stdout.splitlines() 64cc1dc7a3Sopenharmony_ci 65cc1dc7a3Sopenharmony_ci for line in lines: 66cc1dc7a3Sopenharmony_ci match = funcPattern.match(line) 67cc1dc7a3Sopenharmony_ci if match: 68cc1dc7a3Sopenharmony_ci funcName = match.group(1) 69cc1dc7a3Sopenharmony_ci if funcName == symbol: 70cc1dc7a3Sopenharmony_ci funcActive = True 71cc1dc7a3Sopenharmony_ci else: 72cc1dc7a3Sopenharmony_ci funcActive = False 73cc1dc7a3Sopenharmony_ci 74cc1dc7a3Sopenharmony_ci if funcActive: 75cc1dc7a3Sopenharmony_ci funcLines.append(line) 76cc1dc7a3Sopenharmony_ci 77cc1dc7a3Sopenharmony_ci print("\n".join(funcLines)) 78cc1dc7a3Sopenharmony_ci 79cc1dc7a3Sopenharmony_cidef parse_command_line(): 80cc1dc7a3Sopenharmony_ci """ 81cc1dc7a3Sopenharmony_ci Parse the command line. 82cc1dc7a3Sopenharmony_ci 83cc1dc7a3Sopenharmony_ci Returns: 84cc1dc7a3Sopenharmony_ci Namespace: The parsed command line container. 85cc1dc7a3Sopenharmony_ci """ 86cc1dc7a3Sopenharmony_ci parser = argparse.ArgumentParser() 87cc1dc7a3Sopenharmony_ci 88cc1dc7a3Sopenharmony_ci parser.add_argument("binary", type=argparse.FileType("r"), 89cc1dc7a3Sopenharmony_ci help="The new binary to dump") 90cc1dc7a3Sopenharmony_ci 91cc1dc7a3Sopenharmony_ci parser.add_argument("symbol", type=str, 92cc1dc7a3Sopenharmony_ci help="The function name to dump") 93cc1dc7a3Sopenharmony_ci 94cc1dc7a3Sopenharmony_ci return parser.parse_args() 95cc1dc7a3Sopenharmony_ci 96cc1dc7a3Sopenharmony_ci 97cc1dc7a3Sopenharmony_cidef main(): 98cc1dc7a3Sopenharmony_ci """ 99cc1dc7a3Sopenharmony_ci The main function. 100cc1dc7a3Sopenharmony_ci 101cc1dc7a3Sopenharmony_ci Returns: 102cc1dc7a3Sopenharmony_ci int: The process return code. 103cc1dc7a3Sopenharmony_ci """ 104cc1dc7a3Sopenharmony_ci args = parse_command_line() 105cc1dc7a3Sopenharmony_ci 106cc1dc7a3Sopenharmony_ci # Preflight - check that size exists. Note that size might still fail at 107cc1dc7a3Sopenharmony_ci # runtime later, e.g. if the binary is not of the correct format 108cc1dc7a3Sopenharmony_ci path = shutil.which("objdump") 109cc1dc7a3Sopenharmony_ci if not path: 110cc1dc7a3Sopenharmony_ci print("ERROR: The 'objdump' utility is not installed on the PATH") 111cc1dc7a3Sopenharmony_ci return 1 112cc1dc7a3Sopenharmony_ci 113cc1dc7a3Sopenharmony_ci # Collect the data 114cc1dc7a3Sopenharmony_ci try: 115cc1dc7a3Sopenharmony_ci run_objdump(args.binary.name, args.symbol) 116cc1dc7a3Sopenharmony_ci except sp.CalledProcessError as ex: 117cc1dc7a3Sopenharmony_ci print("ERROR: The 'objdump' utility failed") 118cc1dc7a3Sopenharmony_ci print(" %s" % ex.stderr.strip()) 119cc1dc7a3Sopenharmony_ci return 1 120cc1dc7a3Sopenharmony_ci 121cc1dc7a3Sopenharmony_ci return 0 122cc1dc7a3Sopenharmony_ci 123cc1dc7a3Sopenharmony_ci 124cc1dc7a3Sopenharmony_ciif __name__ == "__main__": 125cc1dc7a3Sopenharmony_ci sys.exit(main()) 126