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