xref: /aosp_15_r20/external/toolchain-utils/debug_info_test/check_icf.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 chrome was built with identical code folding."""
7
8
9import os
10import re
11import subprocess
12
13
14def check_identical_code_folding(dso_path):
15    """check whether chrome was built with identical code folding.
16
17    Args:
18      dso_path: path to the dso.
19
20    Returns:
21      False if the dso is chrome and it was not built with icf,
22      True otherwise.
23    """
24
25    if not dso_path.endswith("/chrome.debug"):
26        return True
27
28    # Run 'nm' on the chrome binary and read the output.
29    nm = subprocess.Popen(
30        ["nm", dso_path],
31        stdout=subprocess.PIPE,
32        stderr=open(os.devnull, "w"),
33        encoding="utf-8",
34    )
35    nm_output, _ = nm.communicate()
36
37    # Search for addresses of text symbols.
38    text_addresses = re.findall("^[0-9a-f]+[ ]+[tT] ", nm_output, re.MULTILINE)
39
40    # Calculate number of text symbols in chrome binary.
41    num_text_addresses = len(text_addresses)
42
43    # Calculate number of unique text symbols in chrome binary.
44    num_unique_text_addresses = len(set(text_addresses))
45
46    # Check that the number of duplicate symbols is at least 10,000.
47    #   - https://crbug.com/813272#c18
48    if num_text_addresses - num_unique_text_addresses >= 10000:
49        return True
50
51    print("%s was not built with ICF" % dso_path)
52    print("    num_text_addresses = %d" % num_text_addresses)
53    print("    num_unique_text_addresses = %d" % num_unique_text_addresses)
54    return False
55