brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 4617bd5 Raw
169 lines · python
1#!/usr/bin/env python2 3"""Generate skeletal functions with a variety .cfi_ directives.4The purpose is to produce object-file test inputs to lld with a5variety of compact unwind encodings.6"""7from __future__ import print_function8import random9import argparse10import string11from math import factorial12from itertools import permutations13 14lsda_n = 015lsda_odds = 0.016func_size_low = 0x1017func_size_high = 0x10018saved_regs = ["%r15", "%r14", "%r13", "%r12", "%rbx"]19saved_regs_combined = list(list(permutations(saved_regs, i)) for i in range(0, 6))20 21 22def print_function(name):23    global lsda_odds24    have_lsda = random.random() < lsda_odds25    frame_size = random.randint(4, 64) * 1626    frame_offset = -random.randint(0, int(frame_size / 16 - 4)) * 1627    global func_size_low, func_size_high28    func_size = random.randint(func_size_low, func_size_high) * 0x1029    func_size_high += 130    if func_size_high % 0x10 == 0:31        func_size_low += 132 33    print(34        """\35### %s frame=%d lsda=%s size=%d36    .section __TEXT,__text,regular,pure_instructions37    .p2align 4, 0x9038    .globl %s39%s:40    .cfi_startproc"""41        % (name, frame_size, have_lsda, func_size, name, name)42    )43    if have_lsda:44        global lsda_n45        lsda_n += 146        print(47            """\48    .cfi_personality 155, ___gxx_personality_v049    .cfi_lsda 16, Lexception%d"""50            % lsda_n51        )52    print(53        """\54    pushq %%rbp55    .cfi_def_cfa_offset %d56    .cfi_offset %%rbp, %d57    movq %%rsp, %%rbp58    .cfi_def_cfa_register %%rbp"""59        % (frame_size, frame_offset + 6 * 8)60    )61    print(62        """\63    .fill %d64    popq %%rbp65    retq66    .cfi_endproc67"""68        % (func_size - 6)69    )70 71    if have_lsda:72        print(73            """\74    .section __TEXT,__gcc_except_tab75    .p2align 276Lexception%d:77    .space 0x1078"""79            % lsda_n80        )81    return func_size82 83 84def random_seed():85    """Generate a seed that can easily be passed back in via --seed=STRING"""86    return "".join(random.choice(string.ascii_lowercase) for i in range(10))87 88 89def main():90    parser = argparse.ArgumentParser(91        description=__doc__,92        epilog="""\93Function sizes begin small then monotonically increase.  The goal is94to produce early pages that are full and later pages that are less95than full, in order to test handling for both cases.  Full pages96contain the maximum of 1021 compact unwind entries for a total page97size = 4 KiB.98 99Use --pages=N or --functions=N to control the size of the output.100Default is --pages=2, meaning produce at least two full pages of101compact unwind entries, plus some more. The calculation is sloppy.102""",103    )104    parser.add_argument(105        "--seed",106        type=str,107        default=random_seed(),108        help="Seed the random number generator",109    )110    parser.add_argument(111        "--pages", type=int, default=2, help="Number of compact-unwind pages"112    )113    parser.add_argument(114        "--functions", type=int, default=None, help="Number of functions to generate"115    )116    parser.add_argument(117        "--encodings",118        type=int,119        default=127,120        help="Maximum number of unique unwind encodings (default = 127)",121    )122    parser.add_argument(123        "--lsda",124        type=int,125        default=0,126        help="Percentage of functions with personality & LSDA (default = 10",127    )128    args = parser.parse_args()129    random.seed(args.seed)130    p2align = 14131    global lsda_odds132    lsda_odds = args.lsda / 100.0133 134    print(135        """\136### seed=%s lsda=%f p2align=%d137    .section __TEXT,__text,regular,pure_instructions138    .p2align %d, 0x90139"""140        % (args.seed, lsda_odds, p2align, p2align)141    )142 143    size = 0144    base = 1 << p2align145    if args.functions:146        for n in range(args.functions):147            size += print_function("x%08x" % (size + base))148    else:149        while size < (args.pages << 24):150            size += print_function("x%08x" % (size + base))151 152    print(153        """\154    .section __TEXT,__text,regular,pure_instructions155    .globl _main156    .p2align 4, 0x90157_main:158    retq159 160    .p2align 4, 0x90161___gxx_personality_v0:162    retq163"""164    )165 166 167if __name__ == "__main__":168    main()169