brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 1cc82f8 Raw
128 lines · python
1#!/usr/bin/env python2 3"""Validate compact unwind info by cross checking the llvm-objdump4reports of the input object file vs final linked output.5"""6from __future__ import print_function7import sys8import argparse9import re10from pprint import pprint11 12 13def main():14    hex = r"[a-f\d]"15    hex8 = hex + "{8}"16 17    parser = argparse.ArgumentParser(description=__doc__)18    parser.add_argument(19        "files",20        metavar="FILES",21        nargs="*",22        help="output of (llvm-objdump --unwind-info --syms) for object file(s) plus final linker output",23    )24    parser.add_argument("--debug", action="store_true")25    args = parser.parse_args()26 27    if args.files:28        objdump_string = "".join([open(f).read() for f in args.files])29    else:30        objdump_string = sys.stdin.read()31 32    object_encodings_list = [33        (symbol, encoding, personality, lsda)34        for symbol, encoding, personality, lsda in re.findall(35            r"start:\s+0x%s+\s+(\w+)\s+" % hex36            + r"length:\s+0x%s+\s+" % hex37            + r"compact encoding:\s+0x(%s+)(?:\s+" % hex38            + r"personality function:\s+0x(%s+)\s+\w+\s+" % hex39            + r"LSDA:\s+0x(%s+)\s+\w+(?: \+ 0x%s+)?)?" % (hex, hex),40            objdump_string,41            re.DOTALL,42        )43    ]44    object_encodings_map = {45        symbol: encoding for symbol, encoding, _, _ in object_encodings_list46    }47    if not object_encodings_map:48        sys.exit("no object encodings found in input")49 50    # generate-cfi-funcs.py doesn't generate unwind info for _main.51    object_encodings_map["_main"] = "00000000"52 53    program_symbols_map = {54        address: symbol55        for address, symbol in re.findall(56            r"^%s(%s) g\s+F __TEXT,__text (x\1|_main)$" % (hex8, hex8),57            objdump_string,58            re.MULTILINE,59        )60    }61    if not program_symbols_map:62        sys.exit("no program symbols found in input")63 64    program_common_encodings = re.findall(65        r"^\s+encoding\[(?:\d|\d\d|1[01]\d|12[0-6])\]: 0x(%s+)$" % hex,66        objdump_string,67        re.MULTILINE,68    )69    if not program_common_encodings:70        sys.exit("no common encodings found in input")71 72    program_encodings_map = {73        program_symbols_map[address]: encoding74        for address, encoding in re.findall(75            r"^\s+\[\d+\]: function offset=0x(%s+), " % hex76            + r"encoding(?:\[\d+\])?=0x(%s+)$" % hex,77            objdump_string,78            re.MULTILINE,79        )80    }81    if not object_encodings_map:82        sys.exit("no program encodings found in input")83 84    # Fold adjacent entries from the object file that have matching encodings85    # TODO(gkm) add check for personality+lsda86    encoding0 = 087    for symbol in sorted(object_encodings_map):88        encoding = object_encodings_map[symbol]89        fold = encoding == encoding090        if fold:91            del object_encodings_map[symbol]92        if args.debug:93            print("%s %s with %s" % ("delete" if fold else "retain", symbol, encoding))94        encoding0 = encoding95 96    if program_encodings_map != object_encodings_map:97        if args.debug:98            print("program encodings map:")99            pprint(program_encodings_map)100            print("object encodings map:")101            pprint(object_encodings_map)102        sys.exit("encoding maps differ")103 104    # Count frequency of object-file folded encodings105    # and compare with the program-file common encodings table106    encoding_frequency_map = {}107    for _, encoding in object_encodings_map.items():108        encoding_frequency_map[encoding] = 1 + encoding_frequency_map.get(encoding, 0)109    encoding_frequencies = [110        x111        for x in sorted(112            encoding_frequency_map,113            key=lambda x: (encoding_frequency_map.get(x), x),114            reverse=True,115        )116    ]117    del encoding_frequencies[127:]118 119    if program_common_encodings != encoding_frequencies:120        if args.debug:121            pprint("program common encodings:\n" + str(program_common_encodings))122            pprint("object encoding frequencies:\n" + str(encoding_frequencies))123        sys.exit("encoding frequencies differ")124 125 126if __name__ == "__main__":127    main()128