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 compile units.""" 7*760c253cSXin Li 8*760c253cSXin Li 9*760c253cSXin Liimport os 10*760c253cSXin Liimport subprocess 11*760c253cSXin Li 12*760c253cSXin Liimport check_ngcc 13*760c253cSXin Li 14*760c253cSXin Li 15*760c253cSXin Licu_checks = [check_ngcc.not_by_gcc] 16*760c253cSXin Li 17*760c253cSXin Li 18*760c253cSXin Lidef check_compile_unit(dso_path, producer, comp_path): 19*760c253cSXin Li """check all compiler flags used to build the compile unit. 20*760c253cSXin Li 21*760c253cSXin Li Args: 22*760c253cSXin Li dso_path: path to the elf/dso. 23*760c253cSXin Li producer: DW_AT_producer contains the compiler command line. 24*760c253cSXin Li comp_path: DW_AT_comp_dir + DW_AT_name. 25*760c253cSXin Li 26*760c253cSXin Li Returns: 27*760c253cSXin Li A set of failed tests. 28*760c253cSXin Li """ 29*760c253cSXin Li failed = set() 30*760c253cSXin Li for c in cu_checks: 31*760c253cSXin Li if not c(dso_path, producer, comp_path): 32*760c253cSXin Li failed.add(c.__module__) 33*760c253cSXin Li 34*760c253cSXin Li return failed 35*760c253cSXin Li 36*760c253cSXin Li 37*760c253cSXin Lidef check_compile_units(dso_path): 38*760c253cSXin Li """check all compile units in the given dso. 39*760c253cSXin Li 40*760c253cSXin Li Args: 41*760c253cSXin Li dso_path: path to the dso. 42*760c253cSXin Li 43*760c253cSXin Li Returns: 44*760c253cSXin Li True if everything looks fine otherwise False. 45*760c253cSXin Li """ 46*760c253cSXin Li 47*760c253cSXin Li failed = set() 48*760c253cSXin Li producer = "" 49*760c253cSXin Li comp_path = "" 50*760c253cSXin Li 51*760c253cSXin Li readelf = subprocess.Popen( 52*760c253cSXin Li ["llvm-dwarfdump", "--recurse-depth=0", dso_path], 53*760c253cSXin Li stdout=subprocess.PIPE, 54*760c253cSXin Li stderr=open(os.devnull, "w"), 55*760c253cSXin Li encoding="utf-8", 56*760c253cSXin Li ) 57*760c253cSXin Li for l in readelf.stdout: 58*760c253cSXin Li if "DW_TAG_compile_unit" in l: 59*760c253cSXin Li if producer: 60*760c253cSXin Li failed = failed.union( 61*760c253cSXin Li check_compile_unit(dso_path, producer, comp_path) 62*760c253cSXin Li ) 63*760c253cSXin Li producer = "" 64*760c253cSXin Li comp_path = "" 65*760c253cSXin Li elif "DW_AT_producer" in l: 66*760c253cSXin Li producer = l 67*760c253cSXin Li elif "DW_AT_name" in l: 68*760c253cSXin Li comp_path = os.path.join(comp_path, l.split(":")[-1].strip()) 69*760c253cSXin Li elif "DW_AT_comp_dir" in l: 70*760c253cSXin Li comp_path = os.path.join(l.split(":")[-1].strip(), comp_path) 71*760c253cSXin Li if producer: 72*760c253cSXin Li failed = failed.union(check_compile_unit(dso_path, producer, comp_path)) 73*760c253cSXin Li 74*760c253cSXin Li if failed: 75*760c253cSXin Li print("%s failed check: %s" % (dso_path, " ".join(failed))) 76*760c253cSXin Li return False 77*760c253cSXin Li 78*760c253cSXin Li return True 79