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