xref: /llvm-project/lld/test/MachO/tools/generate-thunkable-program.py (revision f98ee40f4b5d7474fc67e82824bf6abbaedb7b1c)
1#!/usr/bin/env python3
2
3"""Generate many skeletal functions with a thick call graph spanning a
4large address space to induce lld to create branch-islands for arm64.
5
6"""
7from __future__ import print_function
8import random
9import argparse
10import string
11from pprint import pprint
12from math import factorial
13from itertools import permutations
14
15# This list comes from libSystem.tbd and contains a sizeable subset
16# of dylib calls available for all MacOS target archs.
17libSystem_calls = (
18    "__CurrentRuneLocale",
19    "__DefaultRuneLocale",
20    "__Exit",
21    "__NSGetArgc",
22    "__NSGetArgv",
23    "__NSGetEnviron",
24    "__NSGetMachExecuteHeader",
25    "__NSGetProgname",
26    "__PathLocale",
27    "__Read_RuneMagi",
28    "___Balloc_D2A",
29    "___Bfree_D2A",
30    "___ULtod_D2A",
31    "____mb_cur_max",
32    "____mb_cur_max_l",
33    "____runetype",
34    "____runetype_l",
35    "____tolower",
36    "____tolower_l",
37    "____toupper",
38    "____toupper_l",
39    "___add_ovflpage",
40    "___addel",
41    "___any_on_D2A",
42    "___assert_rtn",
43    "___b2d_D2A",
44    "___big_delete",
45    "___big_insert",
46    "___big_keydata",
47    "___big_return",
48    "___big_split",
49    "___bigtens_D2A",
50    "___bt_close",
51    "___bt_cmp",
52    "___bt_defcmp",
53    "___bt_defpfx",
54    "___bt_delete",
55    "___bt_dleaf",
56    "___bt_fd",
57    "___bt_free",
58    "___bt_get",
59    "___bt_new",
60    "___bt_open",
61    "___bt_pgin",
62    "___bt_pgout",
63    "___bt_put",
64    "___bt_ret",
65    "___bt_search",
66    "___bt_seq",
67    "___bt_setcur",
68    "___bt_split",
69    "___bt_sync",
70    "___buf_free",
71    "___call_hash",
72    "___cleanup",
73    "___cmp_D2A",
74    "___collate_equiv_match",
75    "___collate_load_error",
76    "___collate_lookup",
77    "___collate_lookup_l",
78    "___copybits_D2A",
79    "___cxa_atexit",
80    "___cxa_finalize",
81    "___cxa_finalize_ranges",
82    "___cxa_thread_atexit",
83    "___d2b_D2A",
84    "___dbpanic",
85    "___decrement_D2A",
86    "___default_hash",
87    "___default_utx",
88    "___delpair",
89    "___diff_D2A",
90    "___dtoa",
91    "___expand_table",
92    "___fflush",
93    "___fgetwc",
94    "___find_bigpair",
95    "___find_last_page",
96    "___fix_locale_grouping_str",
97    "___fread",
98    "___free_ovflpage",
99    "___freedtoa",
100    "___gdtoa",
101    "___gdtoa_locks",
102    "___get_buf",
103    "___get_page",
104    "___gethex_D2A",
105    "___getonlyClocaleconv",
106    "___hash_open",
107    "___hdtoa",
108    "___hexdig_D2A",
109    "___hexdig_init_D2A",
110    "___hexnan_D2A",
111    "___hi0bits_D2A",
112    "___hldtoa",
113    "___i2b_D2A",
114    "___ibitmap",
115    "___increment_D2A",
116    "___isctype",
117    "___istype",
118    "___istype_l",
119    "___ldtoa",
120    "___libc_init",
121    "___lo0bits_D2A",
122    "___log2",
123    "___lshift_D2A",
124    "___maskrune",
125    "___maskrune_l",
126    "___match_D2A",
127    "___mb_cur_max",
128    "___mb_sb_limit",
129    "___memccpy_chk",
130    "___memcpy_chk",
131    "___memmove_chk",
132    "___memset_chk",
133    "___mult_D2A",
134    "___multadd_D2A",
135    "___nrv_alloc_D2A",
136    "___opendir2",
137    "___ovfl_delete",
138    "___ovfl_get",
139    "___ovfl_put",
140    "___pow5mult_D2A",
141    "___put_page",
142    "___quorem_D2A",
143    "___ratio_D2A",
144    "___rec_close",
145    "___rec_delete",
146    "___rec_dleaf",
147    "___rec_fd",
148    "___rec_fmap",
149    "___rec_fpipe",
150    "___rec_get",
151    "___rec_iput",
152    "___rec_open",
153    "___rec_put",
154    "___rec_ret",
155    "___rec_search",
156    "___rec_seq",
157    "___rec_sync",
158    "___rec_vmap",
159    "___rec_vpipe",
160    "___reclaim_buf",
161    "___rshift_D2A",
162    "___rv_alloc_D2A",
163    "___s2b_D2A",
164    "___sF",
165    "___sclose",
166    "___sdidinit",
167    "___set_ones_D2A",
168    "___setonlyClocaleconv",
169    "___sflags",
170    "___sflush",
171    "___sfp",
172    "___sfvwrite",
173    "___sglue",
174    "___sinit",
175    "___slbexpand",
176    "___smakebuf",
177    "___snprintf_chk",
178    "___snprintf_object_size_chk",
179    "___split_page",
180    "___sprintf_chk",
181    "___sprintf_object_size_chk",
182    "___sread",
183    "___srefill",
184    "___srget",
185    "___sseek",
186    "___stack_chk_fail",
187    "___stack_chk_guard",
188    "___stderrp",
189    "___stdinp",
190    "___stdoutp",
191    "___stpcpy_chk",
192    "___stpncpy_chk",
193    "___strcat_chk",
194    "___strcp_D2A",
195    "___strcpy_chk",
196    "___strlcat_chk",
197    "___strlcpy_chk",
198    "___strncat_chk",
199    "___strncpy_chk",
200    "___strtodg",
201    "___strtopdd",
202    "___sum_D2A",
203    "___svfscanf",
204    "___swbuf",
205    "___swhatbuf",
206    "___swrite",
207    "___swsetup",
208    "___tens_D2A",
209    "___tinytens_D2A",
210    "___tolower",
211    "___tolower_l",
212    "___toupper",
213    "___toupper_l",
214    "___trailz_D2A",
215    "___ulp_D2A",
216    "___ungetc",
217    "___ungetwc",
218    "___vsnprintf_chk",
219    "___vsprintf_chk",
220    "___wcwidth",
221    "___wcwidth_l",
222    "__allocenvstate",
223    "__atexit_receipt",
224    "__c_locale",
225    "__cleanup",
226    "__closeutx",
227    "__copyenv",
228    "__cthread_init_routine",
229    "__deallocenvstate",
230    "__endutxent",
231    "__flockfile_debug_stub",
232    "__fseeko",
233    "__ftello",
234    "__fwalk",
235    "__getenvp",
236    "__getutxent",
237    "__getutxid",
238    "__getutxline",
239    "__inet_aton_check",
240    "__init_clock_port",
241    "__int_to_time",
242    "__libc_fork_child",
243    "__libc_initializer",
244    "__long_to_time",
245    "__mkpath_np",
246    "__mktemp",
247    "__openutx",
248    "__os_assert_log",
249    "__os_assert_log_ctx",
250    "__os_assumes_log",
251    "__os_assumes_log_ctx",
252    "__os_avoid_tail_call",
253    "__os_crash",
254    "__os_crash_callback",
255    "__os_crash_fmt",
256    "__os_debug_log",
257    "__os_debug_log_error_str",
258    "__putenvp",
259    "__pututxline",
260    "__rand48_add",
261    "__rand48_mult",
262    "__rand48_seed",
263    "__readdir_unlocked",
264    "__reclaim_telldir",
265    "__seekdir",
266    "__setenvp",
267    "__setutxent",
268    "__sigaction_nobind",
269    "__sigintr",
270    "__signal_nobind",
271    "__sigvec_nobind",
272    "__sread",
273    "__sseek",
274    "__subsystem_init",
275    "__swrite",
276    "__time32_to_time",
277    "__time64_to_time",
278    "__time_to_int",
279    "__time_to_long",
280    "__time_to_time32",
281    "__time_to_time64",
282    "__unsetenvp",
283    "__utmpxname",
284    "_a64l",
285    "_abort",
286    "_abort_report_np",
287    "_abs",
288    "_acl_add_flag_np",
289    "_acl_add_perm",
290    "_acl_calc_mask",
291    "_acl_clear_flags_np",
292    "_acl_clear_perms",
293    "_acl_copy_entry",
294    "_acl_copy_ext",
295    "_acl_copy_ext_native",
296    "_acl_copy_int",
297    "_acl_copy_int_native",
298    "_acl_create_entry",
299    "_acl_create_entry_np",
300    "_acl_delete_def_file",
301    "_acl_delete_entry",
302    "_acl_delete_fd_np",
303    "_acl_delete_file_np",
304    "_acl_delete_flag_np",
305    "_acl_delete_link_np",
306    "_acl_delete_perm",
307    "_acl_dup",
308    "_acl_free",
309    "_acl_from_text",
310    "_acl_get_entry",
311    "_acl_get_fd",
312    "_acl_get_fd_np",
313    "_acl_get_file",
314    "_acl_get_flag_np",
315    "_acl_get_flagset_np",
316    "_acl_get_link_np",
317    "_acl_get_perm_np",
318    "_acl_get_permset",
319    "_acl_get_permset_mask_np",
320    "_acl_get_qualifier",
321    "_acl_get_tag_type",
322    "_acl_init",
323    "_acl_maximal_permset_mask_np",
324    "_acl_set_fd",
325    "_acl_set_fd_np",
326    "_acl_set_file",
327    "_acl_set_flagset_np",
328    "_acl_set_link_np",
329    "_acl_set_permset",
330    "_acl_set_permset_mask_np",
331    "_acl_set_qualifier",
332    "_acl_set_tag_type",
333    "_acl_size",
334    "_acl_to_text",
335    "_acl_valid",
336    "_acl_valid_fd_np",
337    "_acl_valid_file_np",
338    "_acl_valid_link",
339    "_addr2ascii",
340    "_alarm",
341    "_alphasort",
342    "_arc4random",
343    "_arc4random_addrandom",
344    "_arc4random_buf",
345    "_arc4random_stir",
346    "_arc4random_uniform",
347    "_ascii2addr",
348    "_asctime",
349    "_asctime_r",
350    "_asprintf",
351    "_asprintf_l",
352    "_asxprintf",
353    "_asxprintf_exec",
354    "_atexit",
355    "_atexit_b",
356    "_atof",
357    "_atof_l",
358    "_atoi",
359    "_atoi_l",
360    "_atol",
361    "_atol_l",
362    "_atoll",
363    "_atoll_l",
364    "_backtrace",
365    "_backtrace_from_fp",
366    "_backtrace_image_offsets",
367    "_backtrace_symbols",
368    "_backtrace_symbols_fd",
369    "_basename",
370    "_basename_r",
371    "_bcopy",
372    "_brk",
373    "_bsd_signal",
374    "_bsearch",
375    "_bsearch_b",
376    "_btowc",
377    "_btowc_l",
378    "_catclose",
379    "_catgets",
380    "_catopen",
381    "_cfgetispeed",
382    "_cfgetospeed",
383    "_cfmakeraw",
384    "_cfsetispeed",
385    "_cfsetospeed",
386    "_cfsetspeed",
387    "_cgetcap",
388    "_cgetclose",
389    "_cgetent",
390    "_cgetfirst",
391    "_cgetmatch",
392    "_cgetnext",
393    "_cgetnum",
394    "_cgetset",
395    "_cgetstr",
396    "_cgetustr",
397    "_chmodx_np",
398    "_clearerr",
399    "_clearerr_unlocked",
400    "_clock",
401    "_clock_getres",
402    "_clock_gettime",
403    "_clock_gettime_nsec_np",
404    "_clock_port",
405    "_clock_sem",
406    "_clock_settime",
407    "_closedir",
408    "_compat_mode",
409    "_confstr",
410    "_copy_printf_domain",
411    "_creat",
412    "_crypt",
413    "_ctermid",
414    "_ctermid_r",
415    "_ctime",
416    "_ctime_r",
417    "_daemon",
418    "_daylight",
419    "_dbm_clearerr",
420    "_dbm_close",
421    "_dbm_delete",
422    "_dbm_dirfno",
423    "_dbm_error",
424    "_dbm_fetch",
425    "_dbm_firstkey",
426    "_dbm_nextkey",
427    "_dbm_open",
428    "_dbm_store",
429    "_dbopen",
430    "_devname",
431    "_devname_r",
432    "_difftime",
433    "_digittoint",
434    "_digittoint_l",
435    "_dirfd",
436    "_dirname",
437    "_dirname_r",
438    "_div",
439    "_dprintf",
440    "_dprintf_l",
441    "_drand48",
442    "_duplocale",
443    "_dxprintf",
444    "_dxprintf_exec",
445    "_ecvt",
446    "_encrypt",
447    "_endttyent",
448    "_endusershell",
449    "_endutxent",
450    "_endutxent_wtmp",
451    "_erand48",
452    "_err",
453    "_err_set_exit",
454    "_err_set_exit_b",
455    "_err_set_file",
456    "_errc",
457    "_errx",
458    "_execl",
459    "_execle",
460    "_execlp",
461    "_execv",
462    "_execvP",
463    "_execvp",
464    "_exit",
465    "_f_prealloc",
466    "_fchmodx_np",
467    "_fclose",
468    "_fcvt",
469    "_fdopen",
470    "_fdopendir",
471    "_feof",
472    "_feof_unlocked",
473    "_ferror",
474    "_ferror_unlocked",
475    "_fflagstostr",
476    "_fflush",
477    "_fgetc",
478    "_fgetln",
479    "_fgetpos",
480    "_fgetrune",
481    "_fgets",
482    "_fgetwc",
483    "_fgetwc_l",
484    "_fgetwln",
485    "_fgetwln_l",
486    "_fgetws",
487    "_fgetws_l",
488    "_fileno",
489    "_fileno_unlocked",
490    "_filesec_dup",
491    "_filesec_free",
492    "_filesec_get_property",
493    "_filesec_init",
494    "_filesec_query_property",
495    "_filesec_set_property",
496    "_filesec_unset_property",
497    "_flockfile",
498    "_fmemopen",
499    "_fmtcheck",
500    "_fmtmsg",
501    "_fnmatch",
502    "_fopen",
503    "_fork",
504    "_forkpty",
505    "_fparseln",
506    "_fprintf",
507    "_fprintf_l",
508    "_fpurge",
509    "_fputc",
510    "_fputrune",
511    "_fputs",
512    "_fputwc",
513    "_fputwc_l",
514    "_fputws",
515    "_fputws_l",
516    "_fread",
517    "_free_printf_comp",
518    "_free_printf_domain",
519    "_freelocale",
520    "_freopen",
521    "_fscanf",
522    "_fscanf_l",
523    "_fseek",
524    "_fseeko",
525    "_fsetpos",
526    "_fstatvfs",
527    "_fstatx_np",
528    "_fsync_volume_np",
529    "_ftell",
530    "_ftello",
531    "_ftime",
532    "_ftok",
533    "_ftrylockfile",
534    "_fts_children",
535    "_fts_close",
536    "_fts_open",
537    "_fts_open_b",
538    "_fts_read",
539    "_fts_set",
540    "_ftw",
541    "_fungetrune",
542    "_funlockfile",
543    "_funopen",
544    "_fwide",
545    "_fwprintf",
546    "_fwprintf_l",
547    "_fwrite",
548    "_fwscanf",
549    "_fwscanf_l",
550    "_fxprintf",
551    "_fxprintf_exec",
552    "_gcvt",
553    "_getbsize",
554    "_getc",
555    "_getc_unlocked",
556    "_getchar",
557    "_getchar_unlocked",
558    "_getcwd",
559    "_getdate",
560    "_getdate_err",
561    "_getdelim",
562    "_getdiskbyname",
563    "_getenv",
564    "_gethostid",
565    "_gethostname",
566    "_getipv4sourcefilter",
567    "_getlastlogx",
568    "_getlastlogxbyname",
569    "_getline",
570    "_getloadavg",
571    "_getlogin",
572    "_getlogin_r",
573    "_getmntinfo",
574    "_getmntinfo_r_np",
575    "_getmode",
576    "_getopt",
577    "_getopt_long",
578    "_getopt_long_only",
579    "_getpagesize",
580    "_getpass",
581    "_getpeereid",
582    "_getprogname",
583    "_gets",
584    "_getsourcefilter",
585    "_getsubopt",
586    "_gettimeofday",
587    "_getttyent",
588    "_getttynam",
589    "_getusershell",
590    "_getutmp",
591    "_getutmpx",
592    "_getutxent",
593    "_getutxent_wtmp",
594    "_getutxid",
595    "_getutxline",
596    "_getvfsbyname",
597    "_getw",
598    "_getwc",
599    "_getwc_l",
600    "_getwchar",
601    "_getwchar_l",
602    "_getwd",
603    "_glob",
604    "_glob_b",
605    "_globfree",
606    "_gmtime",
607    "_gmtime_r",
608    "_grantpt",
609    "_hash_create",
610    "_hash_destroy",
611    "_hash_purge",
612    "_hash_search",
613    "_hash_stats",
614    "_hash_traverse",
615    "_hcreate",
616    "_hdestroy",
617    "_heapsort",
618    "_heapsort_b",
619    "_hsearch",
620    "_imaxabs",
621    "_imaxdiv",
622    "_inet_addr",
623    "_inet_aton",
624    "_inet_lnaof",
625    "_inet_makeaddr",
626    "_inet_net_ntop",
627    "_inet_net_pton",
628    "_inet_neta",
629    "_inet_netof",
630    "_inet_network",
631    "_inet_nsap_addr",
632    "_inet_nsap_ntoa",
633    "_inet_ntoa",
634    "_inet_ntop",
635    "_inet_ntop4",
636    "_inet_ntop6",
637    "_inet_pton",
638    "_initstate",
639    "_insque",
640    "_isalnum",
641    "_isalnum_l",
642    "_isalpha",
643    "_isalpha_l",
644    "_isascii",
645    "_isatty",
646    "_isblank",
647    "_isblank_l",
648    "_iscntrl",
649    "_iscntrl_l",
650    "_isdigit",
651    "_isdigit_l",
652    "_isgraph",
653    "_isgraph_l",
654    "_ishexnumber",
655    "_ishexnumber_l",
656    "_isideogram",
657    "_isideogram_l",
658    "_islower",
659    "_islower_l",
660    "_isnumber",
661    "_isnumber_l",
662    "_isphonogram",
663    "_isphonogram_l",
664    "_isprint",
665    "_isprint_l",
666    "_ispunct",
667    "_ispunct_l",
668    "_isrune",
669    "_isrune_l",
670    "_isspace",
671    "_isspace_l",
672    "_isspecial",
673    "_isspecial_l",
674    "_isupper",
675    "_isupper_l",
676    "_iswalnum",
677    "_iswalnum_l",
678    "_iswalpha",
679    "_iswalpha_l",
680    "_iswascii",
681    "_iswblank",
682    "_iswblank_l",
683    "_iswcntrl",
684    "_iswcntrl_l",
685    "_iswctype",
686    "_iswctype_l",
687    "_iswdigit",
688    "_iswdigit_l",
689    "_iswgraph",
690    "_iswgraph_l",
691    "_iswhexnumber",
692    "_iswhexnumber_l",
693    "_iswideogram",
694    "_iswideogram_l",
695    "_iswlower",
696    "_iswlower_l",
697    "_iswnumber",
698    "_iswnumber_l",
699    "_iswphonogram",
700    "_iswphonogram_l",
701    "_iswprint",
702    "_iswprint_l",
703    "_iswpunct",
704    "_iswpunct_l",
705    "_iswrune",
706    "_iswrune_l",
707    "_iswspace",
708    "_iswspace_l",
709    "_iswspecial",
710    "_iswspecial_l",
711    "_iswupper",
712    "_iswupper_l",
713    "_iswxdigit",
714    "_iswxdigit_l",
715    "_isxdigit",
716    "_isxdigit_l",
717    "_jrand48",
718    "_kOSThermalNotificationPressureLevelName",
719    "_killpg",
720    "_l64a",
721    "_labs",
722    "_lchflags",
723    "_lchmod",
724    "_lcong48",
725    "_ldiv",
726    "_lfind",
727    "_link_addr",
728    "_link_ntoa",
729    "_llabs",
730    "_lldiv",
731    "_localeconv",
732    "_localeconv_l",
733    "_localtime",
734    "_localtime_r",
735    "_lockf",
736    "_login",
737    "_login_tty",
738    "_logout",
739    "_logwtmp",
740    "_lrand48",
741    "_lsearch",
742    "_lstatx_np",
743    "_lutimes",
744    "_mblen",
745    "_mblen_l",
746    "_mbmb",
747    "_mbrlen",
748    "_mbrlen_l",
749    "_mbrrune",
750    "_mbrtowc",
751    "_mbrtowc_l",
752    "_mbrune",
753    "_mbsinit",
754    "_mbsinit_l",
755    "_mbsnrtowcs",
756    "_mbsnrtowcs_l",
757    "_mbsrtowcs",
758    "_mbsrtowcs_l",
759    "_mbstowcs",
760    "_mbstowcs_l",
761    "_mbtowc",
762    "_mbtowc_l",
763    "_memmem",
764    "_memset_s",
765    "_mergesort",
766    "_mergesort_b",
767    "_mkdirx_np",
768    "_mkdtemp",
769    "_mkdtempat_np",
770    "_mkfifox_np",
771    "_mkostemp",
772    "_mkostemps",
773    "_mkostempsat_np",
774    "_mkpath_np",
775    "_mkpathat_np",
776    "_mkstemp",
777    "_mkstemp_dprotected_np",
778    "_mkstemps",
779    "_mkstempsat_np",
780    "_mktemp",
781    "_mktime",
782    "_monaddition",
783    "_moncontrol",
784    "_moncount",
785    "_moninit",
786    "_monitor",
787    "_monoutput",
788    "_monreset",
789    "_monstartup",
790    "_mpool_close",
791    "_mpool_filter",
792    "_mpool_get",
793    "_mpool_new",
794    "_mpool_open",
795    "_mpool_put",
796    "_mpool_sync",
797    "_mrand48",
798    "_nanosleep",
799    "_new_printf_comp",
800    "_new_printf_domain",
801    "_newlocale",
802    "_nextwctype",
803    "_nextwctype_l",
804    "_nftw",
805    "_nice",
806    "_nl_langinfo",
807    "_nl_langinfo_l",
808    "_nrand48",
809    "_nvis",
810    "_off32",
811    "_off64",
812    "_offtime",
813    "_open_memstream",
814    "_open_with_subsystem",
815    "_open_wmemstream",
816    "_opendev",
817    "_opendir",
818    "_openpty",
819    "_openx_np",
820    "_optarg",
821    "_opterr",
822    "_optind",
823    "_optopt",
824    "_optreset",
825    "_pause",
826    "_pclose",
827    "_perror",
828    "_popen",
829    "_posix2time",
830    "_posix_openpt",
831    "_posix_spawnp",
832    "_printf",
833    "_printf_l",
834    "_psignal",
835    "_psort",
836    "_psort_b",
837    "_psort_r",
838    "_ptsname",
839    "_ptsname_r",
840    "_putc",
841    "_putc_unlocked",
842    "_putchar",
843    "_putchar_unlocked",
844    "_putenv",
845    "_puts",
846    "_pututxline",
847    "_putw",
848    "_putwc",
849    "_putwc_l",
850    "_putwchar",
851    "_putwchar_l",
852    "_qsort",
853    "_qsort_b",
854    "_qsort_r",
855    "_querylocale",
856    "_radixsort",
857    "_raise",
858    "_rand",
859    "_rand_r",
860    "_random",
861    "_rb_tree_count",
862    "_rb_tree_find_node",
863    "_rb_tree_find_node_geq",
864    "_rb_tree_find_node_leq",
865    "_rb_tree_init",
866    "_rb_tree_insert_node",
867    "_rb_tree_iterate",
868    "_rb_tree_remove_node",
869    "_readdir",
870    "_readdir_r",
871    "_readpassphrase",
872    "_reallocf",
873    "_realpath",
874    "_recv",
875    "_regcomp",
876    "_regcomp_l",
877    "_regerror",
878    "_regexec",
879    "_regfree",
880    "_register_printf_domain_function",
881    "_register_printf_domain_render_std",
882    "_regncomp",
883    "_regncomp_l",
884    "_regnexec",
885    "_regwcomp",
886    "_regwcomp_l",
887    "_regwexec",
888    "_regwncomp",
889    "_regwncomp_l",
890    "_regwnexec",
891    "_remove",
892    "_remque",
893    "_rewind",
894    "_rewinddir",
895    "_rindex",
896    "_rpmatch",
897    "_sbrk",
898    "_scandir",
899    "_scandir_b",
900    "_scanf",
901    "_scanf_l",
902    "_seed48",
903    "_seekdir",
904    "_send",
905    "_setbuf",
906    "_setbuffer",
907    "_setenv",
908    "_sethostid",
909    "_sethostname",
910    "_setinvalidrune",
911    "_setipv4sourcefilter",
912    "_setkey",
913    "_setlinebuf",
914    "_setlocale",
915    "_setlogin",
916    "_setmode",
917    "_setpgrp",
918    "_setprogname",
919    "_setrgid",
920    "_setruid",
921    "_setrunelocale",
922    "_setsourcefilter",
923    "_setstate",
924    "_settimeofday",
925    "_setttyent",
926    "_setusershell",
927    "_setutxent",
928    "_setutxent_wtmp",
929    "_setvbuf",
930    "_sigaction",
931    "_sigaddset",
932    "_sigaltstack",
933    "_sigblock",
934    "_sigdelset",
935    "_sigemptyset",
936    "_sigfillset",
937    "_sighold",
938    "_sigignore",
939    "_siginterrupt",
940    "_sigismember",
941    "_signal",
942    "_sigpause",
943    "_sigrelse",
944    "_sigset",
945    "_sigsetmask",
946    "_sigvec",
947    "_skip",
948    "_sl_add",
949    "_sl_find",
950    "_sl_free",
951    "_sl_init",
952    "_sleep",
953    "_snprintf",
954    "_snprintf_l",
955    "_snvis",
956    "_sockatmark",
957    "_sprintf",
958    "_sprintf_l",
959    "_sradixsort",
960    "_srand",
961    "_srand48",
962    "_sranddev",
963    "_srandom",
964    "_srandomdev",
965    "_sscanf",
966    "_sscanf_l",
967    "_stat_with_subsystem",
968    "_statvfs",
969    "_statx_np",
970    "_stpcpy",
971    "_stpncpy",
972    "_strcasecmp",
973    "_strcasecmp_l",
974    "_strcasestr",
975    "_strcasestr_l",
976    "_strcat",
977    "_strcoll",
978    "_strcoll_l",
979    "_strcspn",
980    "_strdup",
981    "_strenvisx",
982    "_strerror",
983    "_strerror_r",
984    "_strfmon",
985    "_strfmon_l",
986    "_strftime",
987    "_strftime_l",
988    "_strmode",
989    "_strncasecmp",
990    "_strncasecmp_l",
991    "_strncat",
992    "_strndup",
993    "_strnstr",
994    "_strnunvis",
995    "_strnunvisx",
996    "_strnvis",
997    "_strnvisx",
998    "_strpbrk",
999    "_strptime",
1000    "_strptime_l",
1001    "_strrchr",
1002    "_strsenvisx",
1003    "_strsep",
1004    "_strsignal",
1005    "_strsignal_r",
1006    "_strsnvis",
1007    "_strsnvisx",
1008    "_strspn",
1009    "_strsvis",
1010    "_strsvisx",
1011    "_strtod",
1012    "_strtod_l",
1013    "_strtof",
1014    "_strtof_l",
1015    "_strtofflags",
1016    "_strtoimax",
1017    "_strtoimax_l",
1018    "_strtok",
1019    "_strtok_r",
1020    "_strtol",
1021    "_strtol_l",
1022    "_strtold",
1023    "_strtold_l",
1024    "_strtoll",
1025    "_strtoll_l",
1026    "_strtonum",
1027    "_strtoq",
1028    "_strtoq_l",
1029    "_strtoul",
1030    "_strtoul_l",
1031    "_strtoull",
1032    "_strtoull_l",
1033    "_strtoumax",
1034    "_strtoumax_l",
1035    "_strtouq",
1036    "_strtouq_l",
1037    "_strunvis",
1038    "_strunvisx",
1039    "_strvis",
1040    "_strvisx",
1041    "_strxfrm",
1042    "_strxfrm_l",
1043    "_suboptarg",
1044    "_svis",
1045    "_swab",
1046    "_swprintf",
1047    "_swprintf_l",
1048    "_swscanf",
1049    "_swscanf_l",
1050    "_sxprintf",
1051    "_sxprintf_exec",
1052    "_sync_volume_np",
1053    "_sys_errlist",
1054    "_sys_nerr",
1055    "_sys_siglist",
1056    "_sys_signame",
1057    "_sysconf",
1058    "_sysctl",
1059    "_sysctlbyname",
1060    "_sysctlnametomib",
1061    "_system",
1062    "_tcdrain",
1063    "_tcflow",
1064    "_tcflush",
1065    "_tcgetattr",
1066    "_tcgetpgrp",
1067    "_tcgetsid",
1068    "_tcsendbreak",
1069    "_tcsetattr",
1070    "_tcsetpgrp",
1071    "_tdelete",
1072    "_telldir",
1073    "_tempnam",
1074    "_tfind",
1075    "_thread_stack_pcs",
1076    "_time",
1077    "_time2posix",
1078    "_timegm",
1079    "_timelocal",
1080    "_timeoff",
1081    "_times",
1082    "_timespec_get",
1083    "_timezone",
1084    "_timingsafe_bcmp",
1085    "_tmpfile",
1086    "_tmpnam",
1087    "_toascii",
1088    "_tolower",
1089    "_tolower_l",
1090    "_toupper",
1091    "_toupper_l",
1092    "_towctrans",
1093    "_towctrans_l",
1094    "_towlower",
1095    "_towlower_l",
1096    "_towupper",
1097    "_towupper_l",
1098    "_tre_ast_new_catenation",
1099    "_tre_ast_new_iter",
1100    "_tre_ast_new_literal",
1101    "_tre_ast_new_node",
1102    "_tre_ast_new_union",
1103    "_tre_compile",
1104    "_tre_fill_pmatch",
1105    "_tre_free",
1106    "_tre_mem_alloc_impl",
1107    "_tre_mem_destroy",
1108    "_tre_mem_new_impl",
1109    "_tre_parse",
1110    "_tre_stack_destroy",
1111    "_tre_stack_new",
1112    "_tre_stack_num_objects",
1113    "_tre_tnfa_run_backtrack",
1114    "_tre_tnfa_run_parallel",
1115    "_tsearch",
1116    "_ttyname",
1117    "_ttyname_r",
1118    "_ttyslot",
1119    "_twalk",
1120    "_tzname",
1121    "_tzset",
1122    "_tzsetwall",
1123    "_ualarm",
1124    "_ulimit",
1125    "_umaskx_np",
1126    "_uname",
1127    "_ungetc",
1128    "_ungetwc",
1129    "_ungetwc_l",
1130    "_unlockpt",
1131    "_unsetenv",
1132    "_unvis",
1133    "_uselocale",
1134    "_usleep",
1135    "_utime",
1136    "_utmpxname",
1137    "_uuid_clear",
1138    "_uuid_compare",
1139    "_uuid_copy",
1140    "_uuid_generate",
1141    "_uuid_generate_random",
1142    "_uuid_generate_time",
1143    "_uuid_is_null",
1144    "_uuid_pack",
1145    "_uuid_parse",
1146    "_uuid_unpack",
1147    "_uuid_unparse",
1148    "_uuid_unparse_lower",
1149    "_uuid_unparse_upper",
1150    "_vasprintf",
1151    "_vasprintf_l",
1152    "_vasxprintf",
1153    "_vasxprintf_exec",
1154    "_vdprintf",
1155    "_vdprintf_l",
1156    "_vdxprintf",
1157    "_vdxprintf_exec",
1158    "_verr",
1159    "_verrc",
1160    "_verrx",
1161    "_vfprintf",
1162    "_vfprintf_l",
1163    "_vfscanf",
1164    "_vfscanf_l",
1165    "_vfwprintf",
1166    "_vfwprintf_l",
1167    "_vfwscanf",
1168    "_vfwscanf_l",
1169    "_vfxprintf",
1170    "_vfxprintf_exec",
1171    "_vis",
1172    "_vprintf",
1173    "_vprintf_l",
1174    "_vscanf",
1175    "_vscanf_l",
1176    "_vsnprintf",
1177    "_vsnprintf_l",
1178    "_vsprintf",
1179    "_vsprintf_l",
1180    "_vsscanf",
1181    "_vsscanf_l",
1182    "_vswprintf",
1183    "_vswprintf_l",
1184    "_vswscanf",
1185    "_vswscanf_l",
1186    "_vsxprintf",
1187    "_vsxprintf_exec",
1188    "_vwarn",
1189    "_vwarnc",
1190    "_vwarnx",
1191    "_vwprintf",
1192    "_vwprintf_l",
1193    "_vwscanf",
1194    "_vwscanf_l",
1195    "_vxprintf",
1196    "_vxprintf_exec",
1197    "_wait",
1198    "_wait3",
1199    "_waitpid",
1200    "_warn",
1201    "_warnc",
1202    "_warnx",
1203    "_wcpcpy",
1204    "_wcpncpy",
1205    "_wcrtomb",
1206    "_wcrtomb_l",
1207    "_wcscasecmp",
1208    "_wcscasecmp_l",
1209    "_wcscat",
1210    "_wcschr",
1211    "_wcscmp",
1212    "_wcscoll",
1213    "_wcscoll_l",
1214    "_wcscpy",
1215    "_wcscspn",
1216    "_wcsdup",
1217    "_wcsftime",
1218    "_wcsftime_l",
1219    "_wcslcat",
1220    "_wcslcpy",
1221    "_wcslen",
1222    "_wcsncasecmp",
1223    "_wcsncasecmp_l",
1224    "_wcsncat",
1225    "_wcsncmp",
1226    "_wcsncpy",
1227    "_wcsnlen",
1228    "_wcsnrtombs",
1229    "_wcsnrtombs_l",
1230    "_wcspbrk",
1231    "_wcsrchr",
1232    "_wcsrtombs",
1233    "_wcsrtombs_l",
1234    "_wcsspn",
1235    "_wcsstr",
1236    "_wcstod",
1237    "_wcstod_l",
1238    "_wcstof",
1239    "_wcstof_l",
1240    "_wcstoimax",
1241    "_wcstoimax_l",
1242    "_wcstok",
1243    "_wcstol",
1244    "_wcstol_l",
1245    "_wcstold",
1246    "_wcstold_l",
1247    "_wcstoll",
1248    "_wcstoll_l",
1249    "_wcstombs",
1250    "_wcstombs_l",
1251    "_wcstoul",
1252    "_wcstoul_l",
1253    "_wcstoull",
1254    "_wcstoull_l",
1255    "_wcstoumax",
1256    "_wcstoumax_l",
1257    "_wcswidth",
1258    "_wcswidth_l",
1259    "_wcsxfrm",
1260    "_wcsxfrm_l",
1261    "_wctob",
1262    "_wctob_l",
1263    "_wctomb",
1264    "_wctomb_l",
1265    "_wctrans",
1266    "_wctrans_l",
1267    "_wctype",
1268    "_wctype_l",
1269    "_wcwidth",
1270    "_wcwidth_l",
1271    "_wmemchr",
1272    "_wmemcmp",
1273    "_wmemcpy",
1274    "_wmemmove",
1275    "_wmemset",
1276    "_wordexp",
1277    "_wordfree",
1278    "_wprintf",
1279    "_wprintf_l",
1280    "_wscanf",
1281    "_wscanf_l",
1282    "_wtmpxname",
1283    "_xprintf",
1284    "_xprintf_exec",
1285)
1286
1287
1288def print_here_head(name):
1289    print(
1290        """\
1291(tee %s.s |llvm-mc -filetype=obj -triple %s -o %s.o) <<END_OF_FILE &"""
1292        % (name, triple, name)
1293    )
1294
1295
1296def print_here_tail():
1297    print(
1298        """\
1299END_OF_FILE
1300"""
1301    )
1302
1303
1304def print_function_head(p2align, name):
1305    if args.os == "macos":
1306        print(
1307            """\
1308    .section __TEXT,__text,regular,pure_instructions
1309    .p2align %d, 0x90
1310    .globl _%s
1311_%s:"""
1312            % (p2align, name, name)
1313        )
1314    elif args.os == "windows":
1315        print(
1316            """\
1317    .text
1318    .def %s;
1319    .scl 2;
1320    .type 32;
1321    .endef
1322    .globl %s
1323    .p2align %d
1324%s:"""
1325            % (name, name, p2align, name)
1326        )
1327    elif args.os == "linux":
1328        print(
1329            """\
1330    .text
1331    .p2align %d
1332    .globl %s
1333%s:"""
1334            % (p2align, name, name)
1335        )
1336
1337
1338def print_function(addr, size, addrs):
1339    name = "x%08x" % addr
1340    calls = random.randint(0, size >> 12)
1341    print_here_head(name)
1342    print(
1343        """\
1344### %s size=%x calls=%x"""
1345        % (name, size, calls)
1346    )
1347    print_function_head(4, name)
1348    for i in range(calls):
1349        print(
1350            "    bl %sx%08x\n    .p2align 4"
1351            % (
1352                "_" if args.os == "macos" else "",
1353                addrs[random.randint(0, len(addrs) - 1)],
1354            )
1355        )
1356        if args.os == "macos":
1357            print(
1358                "    bl %s\n    .p2align 4"
1359                % (libSystem_calls[random.randint(0, len(libSystem_calls) - 1)])
1360            )
1361    fill = size - 4 * (calls + 1)
1362    assert fill > 0
1363    print(
1364        """\
1365    .fill 0x%x
1366    ret"""
1367        % (fill)
1368    )
1369    print_here_tail()
1370
1371
1372def random_seed():
1373    """Generate a seed that can easily be passed back in via --seed=STRING"""
1374    return "".join(random.choice(string.ascii_lowercase) for i in range(10))
1375
1376
1377def generate_sizes(base, megabytes):
1378    total = 0
1379    while total < megabytes:
1380        size = random.randint(0x100, 0x10000) * 0x10
1381        yield size
1382        total += size
1383
1384
1385def generate_addrs(addr, sizes):
1386    i = 0
1387    while i < len(sizes):
1388        yield addr
1389        addr += sizes[i]
1390        i += 1
1391
1392
1393def main():
1394    parser = argparse.ArgumentParser(
1395        description=__doc__,
1396        epilog="""\
1397WRITEME
1398""",
1399    )
1400    parser.add_argument(
1401        "--seed",
1402        type=str,
1403        default=random_seed(),
1404        help="Seed the random number generator",
1405    )
1406    parser.add_argument(
1407        "--size",
1408        type=int,
1409        default=None,
1410        help="Total text size to generate, in megabytes",
1411    )
1412    parser.add_argument(
1413        "--os", type=str, default="macos", help="Target OS: macos, windows, or linux"
1414    )
1415    global args
1416    args = parser.parse_args()
1417    triples = {
1418        "macos": "arm64-apple-macos",
1419        "linux": "aarch64-pc-linux",
1420        "windows": "aarch64-pc-windows",
1421    }
1422    global triple
1423    triple = triples.get(args.os)
1424
1425    print(
1426        """\
1427### seed=%s triple=%s
1428"""
1429        % (args.seed, triple)
1430    )
1431
1432    random.seed(args.seed)
1433
1434    base = 0x4010
1435    megabytes = (int(args.size) if args.size else 512) * 1024 * 1024
1436    sizes = [size for size in generate_sizes(base, megabytes)]
1437    addrs = [addr for addr in generate_addrs(base, sizes)]
1438
1439    for i in range(len(addrs)):
1440        print_function(addrs[i], sizes[i], addrs)
1441
1442    print_here_head("main")
1443    print(
1444        """\
1445### _x%08x
1446"""
1447        % (addrs[-1] + sizes[-1])
1448    )
1449    print_function_head(14 if args.os == "macos" else 4, "main")
1450    print("    ret")
1451    print_here_tail()
1452    print("wait")
1453
1454
1455if __name__ == "__main__":
1456    main()
1457