From patchwork Fri Mar 4 15:43:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1601204 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=StZfVbhO; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4K9Byk308jz9sGJ for ; Sat, 5 Mar 2022 02:45:50 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id E707283D62; Fri, 4 Mar 2022 16:44:28 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="StZfVbhO"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 3DF3983D66; Fri, 4 Mar 2022 16:44:22 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.2 Received: from mail-io1-xd33.google.com (mail-io1-xd33.google.com [IPv6:2607:f8b0:4864:20::d33]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CE0FF83D3E for ; Fri, 4 Mar 2022 16:43:32 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-io1-xd33.google.com with SMTP id f14so9987800ioz.1 for ; Fri, 04 Mar 2022 07:43:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qe3yOk28ELblX2vK54/mpBm8JlFT1AnI0DZv9dIpCTM=; b=StZfVbhO1oeKMgMHnkj1DSxw764iJBuiLK2mZSgKlGiAGD/EHUW68ws+JJ4I6RRzA+ obisOS/8eUPMLw7oUOaklAsk157P2HROLG/k+fycmn8Ww73rTRzP9qRHjpZAyHkRzmdC KFX9OGnLBLJFKYCrHTW+hQ1AKHc29gEirzNlw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qe3yOk28ELblX2vK54/mpBm8JlFT1AnI0DZv9dIpCTM=; b=KTM5OlZJrttsEq7N/XtKQ+kYLkFYFOmhpe9dopoCbMc0YtXhzEL7aeZ/1VngXlCw83 EFJDguXZy5gxnRoAAiHz5LgsY1kkx1nqfN9f+5/SspHk0PZ3OyIhSWAEzF4EG4CQKlB1 tq+2VR9MZ7I0uHLSBJo5nIznwmuQoB7Ryb4stbTn2y58v8J/SGv3F1DJRmaHhJz+GdVJ sz6CDa7dZHwXRl+X7nuvKX1/bAtBQFTRSxDGl4+e1+z4WmZu//+nTcS5YIyWfPVcY6HT l3YZiDwpbBPxv0Qn/RKji04YtRTbyZeFBdzd5q/z9Fi8sQQRm34hpeFQcCTFzKRePZAa L3zw== X-Gm-Message-State: AOAM532U1f/PyiS8M2Rlj2t75y+GEoi/9EmmC4xVuhrHyNndQhAO+eAV zCU2EP6z7pGcGDUArKWkRw1QVW1w90rW3Q== X-Google-Smtp-Source: ABdhPJwKdhyLPF3GoSozqkbLil/QagZHXvlrYthxw/c2r6iDTiPVH30LlGzLo4GfF1MJ8k2YazB7Cg== X-Received: by 2002:a5d:8510:0:b0:641:61be:4f77 with SMTP id q16-20020a5d8510000000b0064161be4f77mr31246293ion.182.1646408611269; Fri, 04 Mar 2022 07:43:31 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id h13-20020a5ecb4d000000b006410cd7bf4asm4758814iok.9.2022.03.04.07.43.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Mar 2022 07:43:30 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Marek Vasut , Masahiro Yamada , Tom Rini , AKASHI Takahiro , =?utf-8?q?Marek_Beh=C3=BAn?= , Heinrich Schuchardt , Simon Glass Subject: [PATCH v2 12/13] event: Add a script to decode the event-spy list Date: Fri, 4 Mar 2022 08:43:07 -0700 Message-Id: <20220304154308.2547711-13-sjg@chromium.org> X-Mailer: git-send-email 2.35.1.616.g0bdcbb4464-goog In-Reply-To: <20220304154308.2547711-1-sjg@chromium.org> References: <20220304154308.2547711-1-sjg@chromium.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean For debugging and dicoverability it is useful to be able to see a list of each event spy in a U-Boot ELF file. Add a script which shows this, along with the event type and the source location. This makes events a little easier to use than weak functions, for example. Add a basic sandbox test as well. We could provide a test for other boards, but for now, few use events. Signed-off-by: Simon Glass --- Changes in v2: - Update for patman snake-case change - Use a regular expression in the test to avoid dependency on build dir MAINTAINERS | 2 + scripts/event_dump.py | 115 +++++++++++++++++++++++++++++++ test/py/tests/test_event_dump.py | 20 ++++++ 3 files changed, 137 insertions(+) create mode 100755 scripts/event_dump.py create mode 100644 test/py/tests/test_event_dump.py diff --git a/MAINTAINERS b/MAINTAINERS index 6e5c022138..7012cc2b86 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -815,7 +815,9 @@ S: Maintained F: cmd/event.c F: common/event.c F: include/event.h +F: scripts/event_dump.py F: test/common/event.c +F: test/py/tests/test_event_dump.py FASTBOOT S: Orphaned diff --git a/scripts/event_dump.py b/scripts/event_dump.py new file mode 100755 index 0000000000..751f41b183 --- /dev/null +++ b/scripts/event_dump.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ + +"""Decode the evspy_info linker list in a U-Boot ELF image""" + +from argparse import ArgumentParser +import os +import re +import struct +import sys + +our_path = os.path.dirname(os.path.realpath(__file__)) +src_path = os.path.dirname(our_path) + +sys.path.insert(1, os.path.join(our_path, '../tools')) + +from binman import elf +from patman import tools + +PREFIX = '_u_boot_list_2_evspy_info_2_' +RE_EVTYPE = re.compile('%s(.*)' % PREFIX) + +def show_sym(fname, data, endian, evtype, sym): + """Show information about an evspy entry + + Args: + fname (str): Filename of ELF file + data (bytes): Data for this symbol + endian (str): Endianness to use ('little', 'big', 'auto') + evtype (str): Event type, e.g. 'MISC_INIT_F' + sym (elf.Symbol): Symbol to show + """ + def _unpack_val(sym_data, offset): + start = offset * func_size + val_data = sym_data[start:start + func_size] + fmt = '%s%s' % ('>' if endian == 'big' else '<', + 'L' if func_size == 4 else 'Q') + val = struct.unpack(fmt, val_data)[0] + return val + + # Get the data, which is a struct evspy_info + sym_data = data[sym.offset:sym.offset + sym.size] + + # Figure out the word size of the struct + func_size = 4 if sym.size < 16 else 8 + + # Read the function name for evspy_info->func + while True: + # Switch to big-endian if we see a failure + func_addr = _unpack_val(sym_data, 0) + func_name = elf.GetSymbolFromAddress(fname, func_addr) + if not func_name and endian == 'auto': + endian = 'big' + else: + break + has_id = sym.size in [12, 24] + if has_id: + # Find the address of evspy_info->id in the ELF + id_addr = _unpack_val(sym_data, 2) + + # Get the file offset for that address + id_ofs = elf.GetFileOffset(fname, id_addr) + + # Read out a nul-terminated string + id_data = data[id_ofs:id_ofs + 80] + pos = id_data.find(0) + if pos: + id_data = id_data[:pos] + id_str = id_data.decode('utf-8') + else: + id_str = None + + # Find the file/line for the function + cmd = ['addr2line', '-e', fname, '%x' % func_addr] + out = tools.run(*cmd).strip() + + # Drop the full path if it is the current directory + if out.startswith(src_path): + out = out[len(src_path) + 1:] + print('%-20s %-30s %s' % (evtype, id_str or f'f:{func_name}', out)) + +def show_event_spy_list(fname, endian): + """Show a the event-spy- list from a U-Boot image + + Args: + fname (str): Filename of ELF file + endian (str): Endianness to use ('little', 'big', 'auto') + """ + syms = elf.GetSymbolFileOffset(fname, [PREFIX]) + data = tools.read_file(fname) + print('%-20s %-30s %s' % ('Event type', 'Id', 'Source location')) + print('%-20s %-30s %s' % ('-' * 20, '-' * 30, '-' * 30)) + for name, sym in syms.items(): + m_evtype = RE_EVTYPE.search(name) + evtype = m_evtype .group(1) + show_sym(fname, data, endian, evtype, sym) + +def main(argv): + """Main program + + Args: + argv (list of str): List of program arguments, excluding arvg[0] + """ + epilog = 'Show a list of even spies in a U-Boot EFL file' + parser = ArgumentParser(epilog=epilog) + parser.add_argument('elf', type=str, help='ELF file to decode') + parser.add_argument('-e', '--endian', type=str, default='auto', + help='Big-endian image') + parser.add_argument('-t', '--test', action='store_true', + help='Big-endian image') + args = parser.parse_args(argv) + show_event_spy_list(args.elf, args.endian) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/test/py/tests/test_event_dump.py b/test/py/tests/test_event_dump.py new file mode 100644 index 0000000000..b753e804ac --- /dev/null +++ b/test/py/tests/test_event_dump.py @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2021 Google LLC +# Written by Simon Glass + +import pytest +import re +import u_boot_utils as util + +# This is only a partial test - coverting 64-bit sandbox. It does not test +# big-endian images, nor 32-bit images +@pytest.mark.boardspec('sandbox') +def test_event_dump(u_boot_console): + """Test that the "help" command can be executed.""" + cons = u_boot_console + sandbox = cons.config.build_dir + '/u-boot' + out = util.run_and_log(cons, ['scripts/event_dump.py', sandbox]) + expect = '''.*Event type Id Source location +-------------------- ------------------------------ ------------------------------ +EVT_MISC_INIT_F sandbox_misc_init_f .*arch/sandbox/cpu/start.c:''' + assert re.match(expect, out, re.MULTILINE) is not None