From aef6d17c8d8b39473557a2177a0d3e188c4704ff Mon Sep 17 00:00:00 2001 From: Russell Gallop Date: Wed, 3 Jun 2015 14:33:57 +0000 Subject: [PATCH] [utils] Add exact check to check_cfc.py dash_s_no_change. Files compiled with -via-file-asm should be byte for byte identical. This change improves the checking on dash_s_no_change to detect non-code differences. If there is a difference, the check goes on to compare code and debug to try and be more informative. llvm-svn: 238926 --- clang/utils/check_cfc/check_cfc.py | 24 ++++++++++++++++++------ clang/utils/check_cfc/obj_diff.py | 26 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/clang/utils/check_cfc/check_cfc.py b/clang/utils/check_cfc/check_cfc.py index 3def36e..df586e9 100755 --- a/clang/utils/check_cfc/check_cfc.py +++ b/clang/utils/check_cfc/check_cfc.py @@ -282,12 +282,24 @@ class dash_s_no_change(WrapperCheck): run_step(alternate_command, my_env, "Error compiling with -via-file-asm") - # Compare disassembly (returns first diff if differs) - difference = obj_diff.compare_object_files(self._output_file_a, - output_file_b) - if difference: - raise WrapperCheckException( - "Code difference detected with -S\n{}".format(difference)) + # Compare if object files are exactly the same + exactly_equal = obj_diff.compare_exact(self._output_file_a, output_file_b) + if not exactly_equal: + # Compare disassembly (returns first diff if differs) + difference = obj_diff.compare_object_files(self._output_file_a, + output_file_b) + if difference: + raise WrapperCheckException( + "Code difference detected with -S\n{}".format(difference)) + + # Code is identical, compare debug info + dbgdifference = obj_diff.compare_debug_info(self._output_file_a, + output_file_b) + if dbgdifference: + raise WrapperCheckException( + "Debug info difference detected with -S\n{}".format(dbgdifference)) + + raise WrapperCheckException("Object files not identical with -S\n") # Clean up temp file if comparison okay os.remove(output_file_b) diff --git a/clang/utils/check_cfc/obj_diff.py b/clang/utils/check_cfc/obj_diff.py index 6f932b3..cc4c2a9 100755 --- a/clang/utils/check_cfc/obj_diff.py +++ b/clang/utils/check_cfc/obj_diff.py @@ -4,6 +4,7 @@ from __future__ import print_function import argparse import difflib +import filecmp import os import subprocess import sys @@ -26,6 +27,15 @@ def disassemble(objfile): sys.exit(1) return filter(keep_line, out.split(os.linesep)) +def dump_debug(objfile): + """Dump all of the debug info from a file.""" + p = subprocess.Popen([disassembler, '-WliaprmfsoRt', objfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (out, err) = p.communicate() + if p.returncode or err: + print("Dump debug failed: {}".format(objfile)) + sys.exit(1) + return filter(keep_line, out.split(os.linesep)) + def first_diff(a, b, fromfile, tofile): """Returns the first few lines of a difference, if there is one. Python diff can be very slow with large objects and the most interesting changes @@ -63,6 +73,22 @@ def compare_object_files(objfilea, objfileb): disb = disassemble(objfileb) return first_diff(disa, disb, objfilea, objfileb) +def compare_debug_info(objfilea, objfileb): + """Compare debug info of two different files. + Allowing unavoidable differences, such as filenames. + Return the first difference if the debug info differs, or None. + If there are differences in the code, there will almost certainly be differences in the debug info too. + """ + dbga = dump_debug(objfilea) + dbgb = dump_debug(objfileb) + return first_diff(dbga, dbgb, objfilea, objfileb) + +def compare_exact(objfilea, objfileb): + """Byte for byte comparison between object files. + Returns True if equal, False otherwise. + """ + return filecmp.cmp(objfilea, objfileb) + if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('objfilea', nargs=1) -- 2.7.4