Index: utils/check_cfc/check_cfc.py =================================================================== --- utils/check_cfc/check_cfc.py +++ utils/check_cfc/check_cfc.py @@ -282,12 +282,24 @@ 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) Index: utils/check_cfc/obj_diff.py =================================================================== --- utils/check_cfc/obj_diff.py +++ utils/check_cfc/obj_diff.py @@ -4,6 +4,7 @@ import argparse import difflib +import filecmp import os import subprocess import sys @@ -26,6 +27,15 @@ 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 @@ 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)