| #!/usr/bin/env python3 |
| |
| """Generate many skeletal functions with a thick call graph spanning a |
| large address space to induce lld to create branch-islands for arm64. |
| |
| """ |
| from __future__ import print_function |
| import random |
| import argparse |
| import string |
| from pprint import pprint |
| from math import factorial |
| from itertools import permutations |
| |
| # This list comes from libSystem.tbd and contains a sizeable subset |
| # of dylib calls available for all MacOS target archs. |
| libSystem_calls = ( |
| "__CurrentRuneLocale", |
| "__DefaultRuneLocale", |
| "__Exit", |
| "__NSGetArgc", |
| "__NSGetArgv", |
| "__NSGetEnviron", |
| "__NSGetMachExecuteHeader", |
| "__NSGetProgname", |
| "__PathLocale", |
| "__Read_RuneMagi", |
| "___Balloc_D2A", |
| "___Bfree_D2A", |
| "___ULtod_D2A", |
| "____mb_cur_max", |
| "____mb_cur_max_l", |
| "____runetype", |
| "____runetype_l", |
| "____tolower", |
| "____tolower_l", |
| "____toupper", |
| "____toupper_l", |
| "___add_ovflpage", |
| "___addel", |
| "___any_on_D2A", |
| "___assert_rtn", |
| "___b2d_D2A", |
| "___big_delete", |
| "___big_insert", |
| "___big_keydata", |
| "___big_return", |
| "___big_split", |
| "___bigtens_D2A", |
| "___bt_close", |
| "___bt_cmp", |
| "___bt_defcmp", |
| "___bt_defpfx", |
| "___bt_delete", |
| "___bt_dleaf", |
| "___bt_fd", |
| "___bt_free", |
| "___bt_get", |
| "___bt_new", |
| "___bt_open", |
| "___bt_pgin", |
| "___bt_pgout", |
| "___bt_put", |
| "___bt_ret", |
| "___bt_search", |
| "___bt_seq", |
| "___bt_setcur", |
| "___bt_split", |
| "___bt_sync", |
| "___buf_free", |
| "___call_hash", |
| "___cleanup", |
| "___cmp_D2A", |
| "___collate_equiv_match", |
| "___collate_load_error", |
| "___collate_lookup", |
| "___collate_lookup_l", |
| "___copybits_D2A", |
| "___cxa_atexit", |
| "___cxa_finalize", |
| "___cxa_finalize_ranges", |
| "___cxa_thread_atexit", |
| "___d2b_D2A", |
| "___dbpanic", |
| "___decrement_D2A", |
| "___default_hash", |
| "___default_utx", |
| "___delpair", |
| "___diff_D2A", |
| "___dtoa", |
| "___expand_table", |
| "___fflush", |
| "___fgetwc", |
| "___find_bigpair", |
| "___find_last_page", |
| "___fix_locale_grouping_str", |
| "___fread", |
| "___free_ovflpage", |
| "___freedtoa", |
| "___gdtoa", |
| "___gdtoa_locks", |
| "___get_buf", |
| "___get_page", |
| "___gethex_D2A", |
| "___getonlyClocaleconv", |
| "___hash_open", |
| "___hdtoa", |
| "___hexdig_D2A", |
| "___hexdig_init_D2A", |
| "___hexnan_D2A", |
| "___hi0bits_D2A", |
| "___hldtoa", |
| "___i2b_D2A", |
| "___ibitmap", |
| "___increment_D2A", |
| "___isctype", |
| "___istype", |
| "___istype_l", |
| "___ldtoa", |
| "___libc_init", |
| "___lo0bits_D2A", |
| "___log2", |
| "___lshift_D2A", |
| "___maskrune", |
| "___maskrune_l", |
| "___match_D2A", |
| "___mb_cur_max", |
| "___mb_sb_limit", |
| "___memccpy_chk", |
| "___memcpy_chk", |
| "___memmove_chk", |
| "___memset_chk", |
| "___mult_D2A", |
| "___multadd_D2A", |
| "___nrv_alloc_D2A", |
| "___opendir2", |
| "___ovfl_delete", |
| "___ovfl_get", |
| "___ovfl_put", |
| "___pow5mult_D2A", |
| "___put_page", |
| "___quorem_D2A", |
| "___ratio_D2A", |
| "___rec_close", |
| "___rec_delete", |
| "___rec_dleaf", |
| "___rec_fd", |
| "___rec_fmap", |
| "___rec_fpipe", |
| "___rec_get", |
| "___rec_iput", |
| "___rec_open", |
| "___rec_put", |
| "___rec_ret", |
| "___rec_search", |
| "___rec_seq", |
| "___rec_sync", |
| "___rec_vmap", |
| "___rec_vpipe", |
| "___reclaim_buf", |
| "___rshift_D2A", |
| "___rv_alloc_D2A", |
| "___s2b_D2A", |
| "___sF", |
| "___sclose", |
| "___sdidinit", |
| "___set_ones_D2A", |
| "___setonlyClocaleconv", |
| "___sflags", |
| "___sflush", |
| "___sfp", |
| "___sfvwrite", |
| "___sglue", |
| "___sinit", |
| "___slbexpand", |
| "___smakebuf", |
| "___snprintf_chk", |
| "___snprintf_object_size_chk", |
| "___split_page", |
| "___sprintf_chk", |
| "___sprintf_object_size_chk", |
| "___sread", |
| "___srefill", |
| "___srget", |
| "___sseek", |
| "___stack_chk_fail", |
| "___stack_chk_guard", |
| "___stderrp", |
| "___stdinp", |
| "___stdoutp", |
| "___stpcpy_chk", |
| "___stpncpy_chk", |
| "___strcat_chk", |
| "___strcp_D2A", |
| "___strcpy_chk", |
| "___strlcat_chk", |
| "___strlcpy_chk", |
| "___strncat_chk", |
| "___strncpy_chk", |
| "___strtodg", |
| "___strtopdd", |
| "___sum_D2A", |
| "___svfscanf", |
| "___swbuf", |
| "___swhatbuf", |
| "___swrite", |
| "___swsetup", |
| "___tens_D2A", |
| "___tinytens_D2A", |
| "___tolower", |
| "___tolower_l", |
| "___toupper", |
| "___toupper_l", |
| "___trailz_D2A", |
| "___ulp_D2A", |
| "___ungetc", |
| "___ungetwc", |
| "___vsnprintf_chk", |
| "___vsprintf_chk", |
| "___wcwidth", |
| "___wcwidth_l", |
| "__allocenvstate", |
| "__atexit_receipt", |
| "__c_locale", |
| "__cleanup", |
| "__closeutx", |
| "__copyenv", |
| "__cthread_init_routine", |
| "__deallocenvstate", |
| "__endutxent", |
| "__flockfile_debug_stub", |
| "__fseeko", |
| "__ftello", |
| "__fwalk", |
| "__getenvp", |
| "__getutxent", |
| "__getutxid", |
| "__getutxline", |
| "__inet_aton_check", |
| "__init_clock_port", |
| "__int_to_time", |
| "__libc_fork_child", |
| "__libc_initializer", |
| "__long_to_time", |
| "__mkpath_np", |
| "__mktemp", |
| "__openutx", |
| "__os_assert_log", |
| "__os_assert_log_ctx", |
| "__os_assumes_log", |
| "__os_assumes_log_ctx", |
| "__os_avoid_tail_call", |
| "__os_crash", |
| "__os_crash_callback", |
| "__os_crash_fmt", |
| "__os_debug_log", |
| "__os_debug_log_error_str", |
| "__putenvp", |
| "__pututxline", |
| "__rand48_add", |
| "__rand48_mult", |
| "__rand48_seed", |
| "__readdir_unlocked", |
| "__reclaim_telldir", |
| "__seekdir", |
| "__setenvp", |
| "__setutxent", |
| "__sigaction_nobind", |
| "__sigintr", |
| "__signal_nobind", |
| "__sigvec_nobind", |
| "__sread", |
| "__sseek", |
| "__subsystem_init", |
| "__swrite", |
| "__time32_to_time", |
| "__time64_to_time", |
| "__time_to_int", |
| "__time_to_long", |
| "__time_to_time32", |
| "__time_to_time64", |
| "__unsetenvp", |
| "__utmpxname", |
| "_a64l", |
| "_abort", |
| "_abort_report_np", |
| "_abs", |
| "_acl_add_flag_np", |
| "_acl_add_perm", |
| "_acl_calc_mask", |
| "_acl_clear_flags_np", |
| "_acl_clear_perms", |
| "_acl_copy_entry", |
| "_acl_copy_ext", |
| "_acl_copy_ext_native", |
| "_acl_copy_int", |
| "_acl_copy_int_native", |
| "_acl_create_entry", |
| "_acl_create_entry_np", |
| "_acl_delete_def_file", |
| "_acl_delete_entry", |
| "_acl_delete_fd_np", |
| "_acl_delete_file_np", |
| "_acl_delete_flag_np", |
| "_acl_delete_link_np", |
| "_acl_delete_perm", |
| "_acl_dup", |
| "_acl_free", |
| "_acl_from_text", |
| "_acl_get_entry", |
| "_acl_get_fd", |
| "_acl_get_fd_np", |
| "_acl_get_file", |
| "_acl_get_flag_np", |
| "_acl_get_flagset_np", |
| "_acl_get_link_np", |
| "_acl_get_perm_np", |
| "_acl_get_permset", |
| "_acl_get_permset_mask_np", |
| "_acl_get_qualifier", |
| "_acl_get_tag_type", |
| "_acl_init", |
| "_acl_maximal_permset_mask_np", |
| "_acl_set_fd", |
| "_acl_set_fd_np", |
| "_acl_set_file", |
| "_acl_set_flagset_np", |
| "_acl_set_link_np", |
| "_acl_set_permset", |
| "_acl_set_permset_mask_np", |
| "_acl_set_qualifier", |
| "_acl_set_tag_type", |
| "_acl_size", |
| "_acl_to_text", |
| "_acl_valid", |
| "_acl_valid_fd_np", |
| "_acl_valid_file_np", |
| "_acl_valid_link", |
| "_addr2ascii", |
| "_alarm", |
| "_alphasort", |
| "_arc4random", |
| "_arc4random_addrandom", |
| "_arc4random_buf", |
| "_arc4random_stir", |
| "_arc4random_uniform", |
| "_ascii2addr", |
| "_asctime", |
| "_asctime_r", |
| "_asprintf", |
| "_asprintf_l", |
| "_asxprintf", |
| "_asxprintf_exec", |
| "_atexit", |
| "_atexit_b", |
| "_atof", |
| "_atof_l", |
| "_atoi", |
| "_atoi_l", |
| "_atol", |
| "_atol_l", |
| "_atoll", |
| "_atoll_l", |
| "_backtrace", |
| "_backtrace_from_fp", |
| "_backtrace_image_offsets", |
| "_backtrace_symbols", |
| "_backtrace_symbols_fd", |
| "_basename", |
| "_basename_r", |
| "_bcopy", |
| "_brk", |
| "_bsd_signal", |
| "_bsearch", |
| "_bsearch_b", |
| "_btowc", |
| "_btowc_l", |
| "_catclose", |
| "_catgets", |
| "_catopen", |
| "_cfgetispeed", |
| "_cfgetospeed", |
| "_cfmakeraw", |
| "_cfsetispeed", |
| "_cfsetospeed", |
| "_cfsetspeed", |
| "_cgetcap", |
| "_cgetclose", |
| "_cgetent", |
| "_cgetfirst", |
| "_cgetmatch", |
| "_cgetnext", |
| "_cgetnum", |
| "_cgetset", |
| "_cgetstr", |
| "_cgetustr", |
| "_chmodx_np", |
| "_clearerr", |
| "_clearerr_unlocked", |
| "_clock", |
| "_clock_getres", |
| "_clock_gettime", |
| "_clock_gettime_nsec_np", |
| "_clock_port", |
| "_clock_sem", |
| "_clock_settime", |
| "_closedir", |
| "_compat_mode", |
| "_confstr", |
| "_copy_printf_domain", |
| "_creat", |
| "_crypt", |
| "_ctermid", |
| "_ctermid_r", |
| "_ctime", |
| "_ctime_r", |
| "_daemon", |
| "_daylight", |
| "_dbm_clearerr", |
| "_dbm_close", |
| "_dbm_delete", |
| "_dbm_dirfno", |
| "_dbm_error", |
| "_dbm_fetch", |
| "_dbm_firstkey", |
| "_dbm_nextkey", |
| "_dbm_open", |
| "_dbm_store", |
| "_dbopen", |
| "_devname", |
| "_devname_r", |
| "_difftime", |
| "_digittoint", |
| "_digittoint_l", |
| "_dirfd", |
| "_dirname", |
| "_dirname_r", |
| "_div", |
| "_dprintf", |
| "_dprintf_l", |
| "_drand48", |
| "_duplocale", |
| "_dxprintf", |
| "_dxprintf_exec", |
| "_ecvt", |
| "_encrypt", |
| "_endttyent", |
| "_endusershell", |
| "_endutxent", |
| "_endutxent_wtmp", |
| "_erand48", |
| "_err", |
| "_err_set_exit", |
| "_err_set_exit_b", |
| "_err_set_file", |
| "_errc", |
| "_errx", |
| "_execl", |
| "_execle", |
| "_execlp", |
| "_execv", |
| "_execvP", |
| "_execvp", |
| "_exit", |
| "_f_prealloc", |
| "_fchmodx_np", |
| "_fclose", |
| "_fcvt", |
| "_fdopen", |
| "_fdopendir", |
| "_feof", |
| "_feof_unlocked", |
| "_ferror", |
| "_ferror_unlocked", |
| "_fflagstostr", |
| "_fflush", |
| "_fgetc", |
| "_fgetln", |
| "_fgetpos", |
| "_fgetrune", |
| "_fgets", |
| "_fgetwc", |
| "_fgetwc_l", |
| "_fgetwln", |
| "_fgetwln_l", |
| "_fgetws", |
| "_fgetws_l", |
| "_fileno", |
| "_fileno_unlocked", |
| "_filesec_dup", |
| "_filesec_free", |
| "_filesec_get_property", |
| "_filesec_init", |
| "_filesec_query_property", |
| "_filesec_set_property", |
| "_filesec_unset_property", |
| "_flockfile", |
| "_fmemopen", |
| "_fmtcheck", |
| "_fmtmsg", |
| "_fnmatch", |
| "_fopen", |
| "_fork", |
| "_forkpty", |
| "_fparseln", |
| "_fprintf", |
| "_fprintf_l", |
| "_fpurge", |
| "_fputc", |
| "_fputrune", |
| "_fputs", |
| "_fputwc", |
| "_fputwc_l", |
| "_fputws", |
| "_fputws_l", |
| "_fread", |
| "_free_printf_comp", |
| "_free_printf_domain", |
| "_freelocale", |
| "_freopen", |
| "_fscanf", |
| "_fscanf_l", |
| "_fseek", |
| "_fseeko", |
| "_fsetpos", |
| "_fstatvfs", |
| "_fstatx_np", |
| "_fsync_volume_np", |
| "_ftell", |
| "_ftello", |
| "_ftime", |
| "_ftok", |
| "_ftrylockfile", |
| "_fts_children", |
| "_fts_close", |
| "_fts_open", |
| "_fts_open_b", |
| "_fts_read", |
| "_fts_set", |
| "_ftw", |
| "_fungetrune", |
| "_funlockfile", |
| "_funopen", |
| "_fwide", |
| "_fwprintf", |
| "_fwprintf_l", |
| "_fwrite", |
| "_fwscanf", |
| "_fwscanf_l", |
| "_fxprintf", |
| "_fxprintf_exec", |
| "_gcvt", |
| "_getbsize", |
| "_getc", |
| "_getc_unlocked", |
| "_getchar", |
| "_getchar_unlocked", |
| "_getcwd", |
| "_getdate", |
| "_getdate_err", |
| "_getdelim", |
| "_getdiskbyname", |
| "_getenv", |
| "_gethostid", |
| "_gethostname", |
| "_getipv4sourcefilter", |
| "_getlastlogx", |
| "_getlastlogxbyname", |
| "_getline", |
| "_getloadavg", |
| "_getlogin", |
| "_getlogin_r", |
| "_getmntinfo", |
| "_getmntinfo_r_np", |
| "_getmode", |
| "_getopt", |
| "_getopt_long", |
| "_getopt_long_only", |
| "_getpagesize", |
| "_getpass", |
| "_getpeereid", |
| "_getprogname", |
| "_gets", |
| "_getsourcefilter", |
| "_getsubopt", |
| "_gettimeofday", |
| "_getttyent", |
| "_getttynam", |
| "_getusershell", |
| "_getutmp", |
| "_getutmpx", |
| "_getutxent", |
| "_getutxent_wtmp", |
| "_getutxid", |
| "_getutxline", |
| "_getvfsbyname", |
| "_getw", |
| "_getwc", |
| "_getwc_l", |
| "_getwchar", |
| "_getwchar_l", |
| "_getwd", |
| "_glob", |
| "_glob_b", |
| "_globfree", |
| "_gmtime", |
| "_gmtime_r", |
| "_grantpt", |
| "_hash_create", |
| "_hash_destroy", |
| "_hash_purge", |
| "_hash_search", |
| "_hash_stats", |
| "_hash_traverse", |
| "_hcreate", |
| "_hdestroy", |
| "_heapsort", |
| "_heapsort_b", |
| "_hsearch", |
| "_imaxabs", |
| "_imaxdiv", |
| "_inet_addr", |
| "_inet_aton", |
| "_inet_lnaof", |
| "_inet_makeaddr", |
| "_inet_net_ntop", |
| "_inet_net_pton", |
| "_inet_neta", |
| "_inet_netof", |
| "_inet_network", |
| "_inet_nsap_addr", |
| "_inet_nsap_ntoa", |
| "_inet_ntoa", |
| "_inet_ntop", |
| "_inet_ntop4", |
| "_inet_ntop6", |
| "_inet_pton", |
| "_initstate", |
| "_insque", |
| "_isalnum", |
| "_isalnum_l", |
| "_isalpha", |
| "_isalpha_l", |
| "_isascii", |
| "_isatty", |
| "_isblank", |
| "_isblank_l", |
| "_iscntrl", |
| "_iscntrl_l", |
| "_isdigit", |
| "_isdigit_l", |
| "_isgraph", |
| "_isgraph_l", |
| "_ishexnumber", |
| "_ishexnumber_l", |
| "_isideogram", |
| "_isideogram_l", |
| "_islower", |
| "_islower_l", |
| "_isnumber", |
| "_isnumber_l", |
| "_isphonogram", |
| "_isphonogram_l", |
| "_isprint", |
| "_isprint_l", |
| "_ispunct", |
| "_ispunct_l", |
| "_isrune", |
| "_isrune_l", |
| "_isspace", |
| "_isspace_l", |
| "_isspecial", |
| "_isspecial_l", |
| "_isupper", |
| "_isupper_l", |
| "_iswalnum", |
| "_iswalnum_l", |
| "_iswalpha", |
| "_iswalpha_l", |
| "_iswascii", |
| "_iswblank", |
| "_iswblank_l", |
| "_iswcntrl", |
| "_iswcntrl_l", |
| "_iswctype", |
| "_iswctype_l", |
| "_iswdigit", |
| "_iswdigit_l", |
| "_iswgraph", |
| "_iswgraph_l", |
| "_iswhexnumber", |
| "_iswhexnumber_l", |
| "_iswideogram", |
| "_iswideogram_l", |
| "_iswlower", |
| "_iswlower_l", |
| "_iswnumber", |
| "_iswnumber_l", |
| "_iswphonogram", |
| "_iswphonogram_l", |
| "_iswprint", |
| "_iswprint_l", |
| "_iswpunct", |
| "_iswpunct_l", |
| "_iswrune", |
| "_iswrune_l", |
| "_iswspace", |
| "_iswspace_l", |
| "_iswspecial", |
| "_iswspecial_l", |
| "_iswupper", |
| "_iswupper_l", |
| "_iswxdigit", |
| "_iswxdigit_l", |
| "_isxdigit", |
| "_isxdigit_l", |
| "_jrand48", |
| "_kOSThermalNotificationPressureLevelName", |
| "_killpg", |
| "_l64a", |
| "_labs", |
| "_lchflags", |
| "_lchmod", |
| "_lcong48", |
| "_ldiv", |
| "_lfind", |
| "_link_addr", |
| "_link_ntoa", |
| "_llabs", |
| "_lldiv", |
| "_localeconv", |
| "_localeconv_l", |
| "_localtime", |
| "_localtime_r", |
| "_lockf", |
| "_login", |
| "_login_tty", |
| "_logout", |
| "_logwtmp", |
| "_lrand48", |
| "_lsearch", |
| "_lstatx_np", |
| "_lutimes", |
| "_mblen", |
| "_mblen_l", |
| "_mbmb", |
| "_mbrlen", |
| "_mbrlen_l", |
| "_mbrrune", |
| "_mbrtowc", |
| "_mbrtowc_l", |
| "_mbrune", |
| "_mbsinit", |
| "_mbsinit_l", |
| "_mbsnrtowcs", |
| "_mbsnrtowcs_l", |
| "_mbsrtowcs", |
| "_mbsrtowcs_l", |
| "_mbstowcs", |
| "_mbstowcs_l", |
| "_mbtowc", |
| "_mbtowc_l", |
| "_memmem", |
| "_memset_s", |
| "_mergesort", |
| "_mergesort_b", |
| "_mkdirx_np", |
| "_mkdtemp", |
| "_mkdtempat_np", |
| "_mkfifox_np", |
| "_mkostemp", |
| "_mkostemps", |
| "_mkostempsat_np", |
| "_mkpath_np", |
| "_mkpathat_np", |
| "_mkstemp", |
| "_mkstemp_dprotected_np", |
| "_mkstemps", |
| "_mkstempsat_np", |
| "_mktemp", |
| "_mktime", |
| "_monaddition", |
| "_moncontrol", |
| "_moncount", |
| "_moninit", |
| "_monitor", |
| "_monoutput", |
| "_monreset", |
| "_monstartup", |
| "_mpool_close", |
| "_mpool_filter", |
| "_mpool_get", |
| "_mpool_new", |
| "_mpool_open", |
| "_mpool_put", |
| "_mpool_sync", |
| "_mrand48", |
| "_nanosleep", |
| "_new_printf_comp", |
| "_new_printf_domain", |
| "_newlocale", |
| "_nextwctype", |
| "_nextwctype_l", |
| "_nftw", |
| "_nice", |
| "_nl_langinfo", |
| "_nl_langinfo_l", |
| "_nrand48", |
| "_nvis", |
| "_off32", |
| "_off64", |
| "_offtime", |
| "_open_memstream", |
| "_open_with_subsystem", |
| "_open_wmemstream", |
| "_opendev", |
| "_opendir", |
| "_openpty", |
| "_openx_np", |
| "_optarg", |
| "_opterr", |
| "_optind", |
| "_optopt", |
| "_optreset", |
| "_pause", |
| "_pclose", |
| "_perror", |
| "_popen", |
| "_posix2time", |
| "_posix_openpt", |
| "_posix_spawnp", |
| "_printf", |
| "_printf_l", |
| "_psignal", |
| "_psort", |
| "_psort_b", |
| "_psort_r", |
| "_ptsname", |
| "_ptsname_r", |
| "_putc", |
| "_putc_unlocked", |
| "_putchar", |
| "_putchar_unlocked", |
| "_putenv", |
| "_puts", |
| "_pututxline", |
| "_putw", |
| "_putwc", |
| "_putwc_l", |
| "_putwchar", |
| "_putwchar_l", |
| "_qsort", |
| "_qsort_b", |
| "_qsort_r", |
| "_querylocale", |
| "_radixsort", |
| "_raise", |
| "_rand", |
| "_rand_r", |
| "_random", |
| "_rb_tree_count", |
| "_rb_tree_find_node", |
| "_rb_tree_find_node_geq", |
| "_rb_tree_find_node_leq", |
| "_rb_tree_init", |
| "_rb_tree_insert_node", |
| "_rb_tree_iterate", |
| "_rb_tree_remove_node", |
| "_readdir", |
| "_readdir_r", |
| "_readpassphrase", |
| "_reallocf", |
| "_realpath", |
| "_recv", |
| "_regcomp", |
| "_regcomp_l", |
| "_regerror", |
| "_regexec", |
| "_regfree", |
| "_register_printf_domain_function", |
| "_register_printf_domain_render_std", |
| "_regncomp", |
| "_regncomp_l", |
| "_regnexec", |
| "_regwcomp", |
| "_regwcomp_l", |
| "_regwexec", |
| "_regwncomp", |
| "_regwncomp_l", |
| "_regwnexec", |
| "_remove", |
| "_remque", |
| "_rewind", |
| "_rewinddir", |
| "_rindex", |
| "_rpmatch", |
| "_sbrk", |
| "_scandir", |
| "_scandir_b", |
| "_scanf", |
| "_scanf_l", |
| "_seed48", |
| "_seekdir", |
| "_send", |
| "_setbuf", |
| "_setbuffer", |
| "_setenv", |
| "_sethostid", |
| "_sethostname", |
| "_setinvalidrune", |
| "_setipv4sourcefilter", |
| "_setkey", |
| "_setlinebuf", |
| "_setlocale", |
| "_setlogin", |
| "_setmode", |
| "_setpgrp", |
| "_setprogname", |
| "_setrgid", |
| "_setruid", |
| "_setrunelocale", |
| "_setsourcefilter", |
| "_setstate", |
| "_settimeofday", |
| "_setttyent", |
| "_setusershell", |
| "_setutxent", |
| "_setutxent_wtmp", |
| "_setvbuf", |
| "_sigaction", |
| "_sigaddset", |
| "_sigaltstack", |
| "_sigblock", |
| "_sigdelset", |
| "_sigemptyset", |
| "_sigfillset", |
| "_sighold", |
| "_sigignore", |
| "_siginterrupt", |
| "_sigismember", |
| "_signal", |
| "_sigpause", |
| "_sigrelse", |
| "_sigset", |
| "_sigsetmask", |
| "_sigvec", |
| "_skip", |
| "_sl_add", |
| "_sl_find", |
| "_sl_free", |
| "_sl_init", |
| "_sleep", |
| "_snprintf", |
| "_snprintf_l", |
| "_snvis", |
| "_sockatmark", |
| "_sprintf", |
| "_sprintf_l", |
| "_sradixsort", |
| "_srand", |
| "_srand48", |
| "_sranddev", |
| "_srandom", |
| "_srandomdev", |
| "_sscanf", |
| "_sscanf_l", |
| "_stat_with_subsystem", |
| "_statvfs", |
| "_statx_np", |
| "_stpcpy", |
| "_stpncpy", |
| "_strcasecmp", |
| "_strcasecmp_l", |
| "_strcasestr", |
| "_strcasestr_l", |
| "_strcat", |
| "_strcoll", |
| "_strcoll_l", |
| "_strcspn", |
| "_strdup", |
| "_strenvisx", |
| "_strerror", |
| "_strerror_r", |
| "_strfmon", |
| "_strfmon_l", |
| "_strftime", |
| "_strftime_l", |
| "_strmode", |
| "_strncasecmp", |
| "_strncasecmp_l", |
| "_strncat", |
| "_strndup", |
| "_strnstr", |
| "_strnunvis", |
| "_strnunvisx", |
| "_strnvis", |
| "_strnvisx", |
| "_strpbrk", |
| "_strptime", |
| "_strptime_l", |
| "_strrchr", |
| "_strsenvisx", |
| "_strsep", |
| "_strsignal", |
| "_strsignal_r", |
| "_strsnvis", |
| "_strsnvisx", |
| "_strspn", |
| "_strsvis", |
| "_strsvisx", |
| "_strtod", |
| "_strtod_l", |
| "_strtof", |
| "_strtof_l", |
| "_strtofflags", |
| "_strtoimax", |
| "_strtoimax_l", |
| "_strtok", |
| "_strtok_r", |
| "_strtol", |
| "_strtol_l", |
| "_strtold", |
| "_strtold_l", |
| "_strtoll", |
| "_strtoll_l", |
| "_strtonum", |
| "_strtoq", |
| "_strtoq_l", |
| "_strtoul", |
| "_strtoul_l", |
| "_strtoull", |
| "_strtoull_l", |
| "_strtoumax", |
| "_strtoumax_l", |
| "_strtouq", |
| "_strtouq_l", |
| "_strunvis", |
| "_strunvisx", |
| "_strvis", |
| "_strvisx", |
| "_strxfrm", |
| "_strxfrm_l", |
| "_suboptarg", |
| "_svis", |
| "_swab", |
| "_swprintf", |
| "_swprintf_l", |
| "_swscanf", |
| "_swscanf_l", |
| "_sxprintf", |
| "_sxprintf_exec", |
| "_sync_volume_np", |
| "_sys_errlist", |
| "_sys_nerr", |
| "_sys_siglist", |
| "_sys_signame", |
| "_sysconf", |
| "_sysctl", |
| "_sysctlbyname", |
| "_sysctlnametomib", |
| "_system", |
| "_tcdrain", |
| "_tcflow", |
| "_tcflush", |
| "_tcgetattr", |
| "_tcgetpgrp", |
| "_tcgetsid", |
| "_tcsendbreak", |
| "_tcsetattr", |
| "_tcsetpgrp", |
| "_tdelete", |
| "_telldir", |
| "_tempnam", |
| "_tfind", |
| "_thread_stack_pcs", |
| "_time", |
| "_time2posix", |
| "_timegm", |
| "_timelocal", |
| "_timeoff", |
| "_times", |
| "_timespec_get", |
| "_timezone", |
| "_timingsafe_bcmp", |
| "_tmpfile", |
| "_tmpnam", |
| "_toascii", |
| "_tolower", |
| "_tolower_l", |
| "_toupper", |
| "_toupper_l", |
| "_towctrans", |
| "_towctrans_l", |
| "_towlower", |
| "_towlower_l", |
| "_towupper", |
| "_towupper_l", |
| "_tre_ast_new_catenation", |
| "_tre_ast_new_iter", |
| "_tre_ast_new_literal", |
| "_tre_ast_new_node", |
| "_tre_ast_new_union", |
| "_tre_compile", |
| "_tre_fill_pmatch", |
| "_tre_free", |
| "_tre_mem_alloc_impl", |
| "_tre_mem_destroy", |
| "_tre_mem_new_impl", |
| "_tre_parse", |
| "_tre_stack_destroy", |
| "_tre_stack_new", |
| "_tre_stack_num_objects", |
| "_tre_tnfa_run_backtrack", |
| "_tre_tnfa_run_parallel", |
| "_tsearch", |
| "_ttyname", |
| "_ttyname_r", |
| "_ttyslot", |
| "_twalk", |
| "_tzname", |
| "_tzset", |
| "_tzsetwall", |
| "_ualarm", |
| "_ulimit", |
| "_umaskx_np", |
| "_uname", |
| "_ungetc", |
| "_ungetwc", |
| "_ungetwc_l", |
| "_unlockpt", |
| "_unsetenv", |
| "_unvis", |
| "_uselocale", |
| "_usleep", |
| "_utime", |
| "_utmpxname", |
| "_uuid_clear", |
| "_uuid_compare", |
| "_uuid_copy", |
| "_uuid_generate", |
| "_uuid_generate_random", |
| "_uuid_generate_time", |
| "_uuid_is_null", |
| "_uuid_pack", |
| "_uuid_parse", |
| "_uuid_unpack", |
| "_uuid_unparse", |
| "_uuid_unparse_lower", |
| "_uuid_unparse_upper", |
| "_vasprintf", |
| "_vasprintf_l", |
| "_vasxprintf", |
| "_vasxprintf_exec", |
| "_vdprintf", |
| "_vdprintf_l", |
| "_vdxprintf", |
| "_vdxprintf_exec", |
| "_verr", |
| "_verrc", |
| "_verrx", |
| "_vfprintf", |
| "_vfprintf_l", |
| "_vfscanf", |
| "_vfscanf_l", |
| "_vfwprintf", |
| "_vfwprintf_l", |
| "_vfwscanf", |
| "_vfwscanf_l", |
| "_vfxprintf", |
| "_vfxprintf_exec", |
| "_vis", |
| "_vprintf", |
| "_vprintf_l", |
| "_vscanf", |
| "_vscanf_l", |
| "_vsnprintf", |
| "_vsnprintf_l", |
| "_vsprintf", |
| "_vsprintf_l", |
| "_vsscanf", |
| "_vsscanf_l", |
| "_vswprintf", |
| "_vswprintf_l", |
| "_vswscanf", |
| "_vswscanf_l", |
| "_vsxprintf", |
| "_vsxprintf_exec", |
| "_vwarn", |
| "_vwarnc", |
| "_vwarnx", |
| "_vwprintf", |
| "_vwprintf_l", |
| "_vwscanf", |
| "_vwscanf_l", |
| "_vxprintf", |
| "_vxprintf_exec", |
| "_wait", |
| "_wait3", |
| "_waitpid", |
| "_warn", |
| "_warnc", |
| "_warnx", |
| "_wcpcpy", |
| "_wcpncpy", |
| "_wcrtomb", |
| "_wcrtomb_l", |
| "_wcscasecmp", |
| "_wcscasecmp_l", |
| "_wcscat", |
| "_wcschr", |
| "_wcscmp", |
| "_wcscoll", |
| "_wcscoll_l", |
| "_wcscpy", |
| "_wcscspn", |
| "_wcsdup", |
| "_wcsftime", |
| "_wcsftime_l", |
| "_wcslcat", |
| "_wcslcpy", |
| "_wcslen", |
| "_wcsncasecmp", |
| "_wcsncasecmp_l", |
| "_wcsncat", |
| "_wcsncmp", |
| "_wcsncpy", |
| "_wcsnlen", |
| "_wcsnrtombs", |
| "_wcsnrtombs_l", |
| "_wcspbrk", |
| "_wcsrchr", |
| "_wcsrtombs", |
| "_wcsrtombs_l", |
| "_wcsspn", |
| "_wcsstr", |
| "_wcstod", |
| "_wcstod_l", |
| "_wcstof", |
| "_wcstof_l", |
| "_wcstoimax", |
| "_wcstoimax_l", |
| "_wcstok", |
| "_wcstol", |
| "_wcstol_l", |
| "_wcstold", |
| "_wcstold_l", |
| "_wcstoll", |
| "_wcstoll_l", |
| "_wcstombs", |
| "_wcstombs_l", |
| "_wcstoul", |
| "_wcstoul_l", |
| "_wcstoull", |
| "_wcstoull_l", |
| "_wcstoumax", |
| "_wcstoumax_l", |
| "_wcswidth", |
| "_wcswidth_l", |
| "_wcsxfrm", |
| "_wcsxfrm_l", |
| "_wctob", |
| "_wctob_l", |
| "_wctomb", |
| "_wctomb_l", |
| "_wctrans", |
| "_wctrans_l", |
| "_wctype", |
| "_wctype_l", |
| "_wcwidth", |
| "_wcwidth_l", |
| "_wmemchr", |
| "_wmemcmp", |
| "_wmemcpy", |
| "_wmemmove", |
| "_wmemset", |
| "_wordexp", |
| "_wordfree", |
| "_wprintf", |
| "_wprintf_l", |
| "_wscanf", |
| "_wscanf_l", |
| "_wtmpxname", |
| "_xprintf", |
| "_xprintf_exec", |
| ) |
| |
| |
| def print_here_head(name): |
| print( |
| """\ |
| (tee %s.s |llvm-mc -filetype=obj -triple %s -o %s.o) <<END_OF_FILE &""" |
| % (name, triple, name) |
| ) |
| |
| |
| def print_here_tail(): |
| print( |
| """\ |
| END_OF_FILE |
| """ |
| ) |
| |
| |
| def print_function_head(p2align, name): |
| if args.os == "macos": |
| print( |
| """\ |
| .section __TEXT,__text,regular,pure_instructions |
| .p2align %d, 0x90 |
| .globl _%s |
| _%s:""" |
| % (p2align, name, name) |
| ) |
| elif args.os == "windows": |
| print( |
| """\ |
| .text |
| .def %s; |
| .scl 2; |
| .type 32; |
| .endef |
| .globl %s |
| .p2align %d |
| %s:""" |
| % (name, name, p2align, name) |
| ) |
| elif args.os == "linux": |
| print( |
| """\ |
| .text |
| .p2align %d |
| .globl %s |
| %s:""" |
| % (p2align, name, name) |
| ) |
| |
| |
| def print_function(addr, size, addrs): |
| name = "x%08x" % addr |
| calls = random.randint(0, size >> 12) |
| print_here_head(name) |
| print( |
| """\ |
| ### %s size=%x calls=%x""" |
| % (name, size, calls) |
| ) |
| print_function_head(4, name) |
| for i in range(calls): |
| print( |
| " bl %sx%08x\n .p2align 4" |
| % ( |
| "_" if args.os == "macos" else "", |
| addrs[random.randint(0, len(addrs) - 1)], |
| ) |
| ) |
| if args.os == "macos": |
| print( |
| " bl %s\n .p2align 4" |
| % (libSystem_calls[random.randint(0, len(libSystem_calls) - 1)]) |
| ) |
| fill = size - 4 * (calls + 1) |
| assert fill > 0 |
| print( |
| """\ |
| .fill 0x%x |
| ret""" |
| % (fill) |
| ) |
| print_here_tail() |
| |
| |
| def random_seed(): |
| """Generate a seed that can easily be passed back in via --seed=STRING""" |
| return "".join(random.choice(string.ascii_lowercase) for i in range(10)) |
| |
| |
| def generate_sizes(base, megabytes): |
| total = 0 |
| while total < megabytes: |
| size = random.randint(0x100, 0x10000) * 0x10 |
| yield size |
| total += size |
| |
| |
| def generate_addrs(addr, sizes): |
| i = 0 |
| while i < len(sizes): |
| yield addr |
| addr += sizes[i] |
| i += 1 |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser( |
| description=__doc__, |
| epilog="""\ |
| WRITEME |
| """, |
| ) |
| parser.add_argument( |
| "--seed", |
| type=str, |
| default=random_seed(), |
| help="Seed the random number generator", |
| ) |
| parser.add_argument( |
| "--size", |
| type=int, |
| default=None, |
| help="Total text size to generate, in megabytes", |
| ) |
| parser.add_argument( |
| "--os", type=str, default="macos", help="Target OS: macos, windows, or linux" |
| ) |
| global args |
| args = parser.parse_args() |
| triples = { |
| "macos": "arm64-apple-macos", |
| "linux": "aarch64-pc-linux", |
| "windows": "aarch64-pc-windows", |
| } |
| global triple |
| triple = triples.get(args.os) |
| |
| print( |
| """\ |
| ### seed=%s triple=%s |
| """ |
| % (args.seed, triple) |
| ) |
| |
| random.seed(args.seed) |
| |
| base = 0x4010 |
| megabytes = (int(args.size) if args.size else 512) * 1024 * 1024 |
| sizes = [size for size in generate_sizes(base, megabytes)] |
| addrs = [addr for addr in generate_addrs(base, sizes)] |
| |
| for i in range(len(addrs)): |
| print_function(addrs[i], sizes[i], addrs) |
| |
| print_here_head("main") |
| print( |
| """\ |
| ### _x%08x |
| """ |
| % (addrs[-1] + sizes[-1]) |
| ) |
| print_function_head(14 if args.os == "macos" else 4, "main") |
| print(" ret") |
| print_here_tail() |
| print("wait") |
| |
| |
| if __name__ == "__main__": |
| main() |