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