xref: /aosp_15_r20/external/toolchain-utils/debug_info_test/check_exist.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1*760c253cSXin Li# -*- coding: utf-8 -*-
2*760c253cSXin Li# Copyright 2018 The ChromiumOS Authors
3*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be
4*760c253cSXin Li# found in the LICENSE file.
5*760c253cSXin Li
6*760c253cSXin Li"""check whether intended components exists in the given dso."""
7*760c253cSXin Li
8*760c253cSXin Li
9*760c253cSXin Liimport os
10*760c253cSXin Liimport subprocess
11*760c253cSXin Li
12*760c253cSXin Lifrom allowlist import is_allowlisted
13*760c253cSXin Li
14*760c253cSXin Li
15*760c253cSXin Lidef check_debug_info(dso_path, readelf_content):
16*760c253cSXin Li    """Check whether debug info section exists in the elf file.
17*760c253cSXin Li
18*760c253cSXin Li    Args:
19*760c253cSXin Li      dso_path: path to the dso.
20*760c253cSXin Li      readelf_content: debug info dumped by command readelf.
21*760c253cSXin Li
22*760c253cSXin Li    Returns:
23*760c253cSXin Li      True if debug info section exists, otherwise False.
24*760c253cSXin Li    """
25*760c253cSXin Li
26*760c253cSXin Li    # Return True if it is allowlisted
27*760c253cSXin Li    if is_allowlisted("exist_debug_info", dso_path):
28*760c253cSXin Li        return True
29*760c253cSXin Li
30*760c253cSXin Li    for l in readelf_content:
31*760c253cSXin Li        if "debug_info" in l:
32*760c253cSXin Li            return True
33*760c253cSXin Li    return False
34*760c253cSXin Li
35*760c253cSXin Li
36*760c253cSXin Lidef check_producer(dso_path, readelf_content):
37*760c253cSXin Li    """Check whether DW_AT_producer exists in each compile unit.
38*760c253cSXin Li
39*760c253cSXin Li    Args:
40*760c253cSXin Li      dso_path: path to the dso.
41*760c253cSXin Li      readelf_content: debug info dumped by command readelf.
42*760c253cSXin Li
43*760c253cSXin Li    Returns:
44*760c253cSXin Li      True if DW_AT_producer exists in each compile unit, otherwise False.
45*760c253cSXin Li      Notice: If no compile unit in DSO, also return True.
46*760c253cSXin Li    """
47*760c253cSXin Li
48*760c253cSXin Li    # Return True if it is allowlisted
49*760c253cSXin Li    if is_allowlisted("exist_producer", dso_path):
50*760c253cSXin Li        return True
51*760c253cSXin Li
52*760c253cSXin Li    # Indicate if there is a producer under each cu
53*760c253cSXin Li    cur_producer = False
54*760c253cSXin Li
55*760c253cSXin Li    first_cu = True
56*760c253cSXin Li    producer_exist = True
57*760c253cSXin Li
58*760c253cSXin Li    for l in readelf_content:
59*760c253cSXin Li        if "DW_TAG_compile_unit" in l:
60*760c253cSXin Li            if not first_cu and not cur_producer:
61*760c253cSXin Li                producer_exist = False
62*760c253cSXin Li                break
63*760c253cSXin Li            first_cu = False
64*760c253cSXin Li            cur_producer = False
65*760c253cSXin Li        elif "DW_AT_producer" in l:
66*760c253cSXin Li            cur_producer = True
67*760c253cSXin Li
68*760c253cSXin Li    # Check whether last producer of compile unit exists in the elf,
69*760c253cSXin Li    # also return True if no cu in the DSO.
70*760c253cSXin Li    if not first_cu and not cur_producer:
71*760c253cSXin Li        producer_exist = False
72*760c253cSXin Li
73*760c253cSXin Li    return producer_exist
74*760c253cSXin Li
75*760c253cSXin Li
76*760c253cSXin Lidef check_exist_all(dso_path):
77*760c253cSXin Li    """check whether intended components exists in the given dso.
78*760c253cSXin Li
79*760c253cSXin Li    Args:
80*760c253cSXin Li      dso_path: path to the dso.
81*760c253cSXin Li
82*760c253cSXin Li    Returns:
83*760c253cSXin Li      True if everything looks fine otherwise False.
84*760c253cSXin Li    """
85*760c253cSXin Li
86*760c253cSXin Li    readelf = subprocess.Popen(
87*760c253cSXin Li        ["llvm-dwarfdump", "--recurse-depth=0", dso_path],
88*760c253cSXin Li        stdout=subprocess.PIPE,
89*760c253cSXin Li        stderr=open(os.devnull, "w"),
90*760c253cSXin Li        encoding="utf-8",
91*760c253cSXin Li    )
92*760c253cSXin Li    readelf_content = list(readelf.stdout)
93*760c253cSXin Li
94*760c253cSXin Li    exist_checks = [check_debug_info, check_producer]
95*760c253cSXin Li
96*760c253cSXin Li    for e in exist_checks:
97*760c253cSXin Li        if not e(dso_path, readelf_content):
98*760c253cSXin Li            check_failed = e.__module__ + ": " + e.__name__
99*760c253cSXin Li            print("%s failed check: %s" % (dso_path, check_failed))
100*760c253cSXin Li            return False
101*760c253cSXin Li
102*760c253cSXin Li    return True
103