3 """Generate skeletal functions with a variety .cfi_ directives.
4 The purpose is to produce object-file test inputs to lld with a
5 variety of compact unwind encodings.
7 from __future__
import print_function
11 from math
import factorial
12 from itertools
import permutations
17 func_size_high
= 0x100
18 saved_regs
= ["%r15", "%r14", "%r13", "%r12", "%rbx"]
19 saved_regs_combined
= list(list(permutations(saved_regs
, i
)) for i
in range(0, 6))
22 def print_function(name
):
24 have_lsda
= random
.random() < lsda_odds
25 frame_size
= random
.randint(4, 64) * 16
26 frame_offset
= -random
.randint(0, int(frame_size
/ 16 - 4)) * 16
27 global func_size_low
, func_size_high
28 func_size
= random
.randint(func_size_low
, func_size_high
) * 0x10
30 if func_size_high
% 0x10 == 0:
35 ### %s frame=%d lsda=%s size=%d
36 .section __TEXT,__text,regular,pure_instructions
41 % (name
, frame_size
, have_lsda
, func_size
, name
, name
)
48 .cfi_personality 155, ___gxx_personality_v0
49 .cfi_lsda 16, Lexception%d"""
55 .cfi_def_cfa_offset %d
58 .cfi_def_cfa_register %%rbp"""
59 % (frame_size
, frame_offset
+ 6 * 8)
74 .section __TEXT,__gcc_except_tab
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))
90 parser
= argparse
.ArgumentParser(
93 Function sizes begin small then monotonically increase. The goal is
94 to produce early pages that are full and later pages that are less
95 than full, in order to test handling for both cases. Full pages
96 contain the maximum of 1021 compact unwind entries for a total page
99 Use --pages=N or --functions=N to control the size of the output.
100 Default is --pages=2, meaning produce at least two full pages of
101 compact unwind entries, plus some more. The calculation is sloppy.
107 default
=random_seed(),
108 help="Seed the random number generator",
111 "--pages", type=int, default
=2, help="Number of compact-unwind pages"
114 "--functions", type=int, default
=None, help="Number of functions to generate"
120 help="Maximum number of unique unwind encodings (default = 127)",
126 help="Percentage of functions with personality & LSDA (default = 10",
128 args
= parser
.parse_args()
129 random
.seed(args
.seed
)
132 lsda_odds
= args
.lsda
/ 100.0
136 ### seed=%s lsda=%f p2align=%d
137 .section __TEXT,__text,regular,pure_instructions
140 % (args
.seed
, lsda_odds
, p2align
, p2align
)
146 for n
in range(args
.functions
):
147 size
+= print_function("x%08x" % (size
+ base
))
149 while size
< (args
.pages
<< 24):
150 size
+= print_function("x%08x" % (size
+ base
))
154 .section __TEXT,__text,regular,pure_instructions
161 ___gxx_personality_v0:
167 if __name__
== "__main__":