main.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include <stdlib.h>
  6. #include "bh_platform.h"
  7. #include "bh_read_file.h"
  8. #include "wasm_export.h"
  9. #include "aot_export.h"
  10. #if BH_HAS_DLFCN
  11. #include <dlfcn.h>
  12. typedef uint32 (*get_native_lib_func)(char **p_module_name,
  13. NativeSymbol **p_native_symbols);
  14. static uint32
  15. load_and_register_native_libs(const char **native_lib_list,
  16. uint32 native_lib_count,
  17. void **native_handle_list)
  18. {
  19. uint32 i, native_handle_count = 0, n_native_symbols;
  20. NativeSymbol *native_symbols;
  21. char *module_name;
  22. void *handle;
  23. for (i = 0; i < native_lib_count; i++) {
  24. /* open the native library */
  25. if (!(handle = dlopen(native_lib_list[i], RTLD_NOW | RTLD_GLOBAL))
  26. && !(handle = dlopen(native_lib_list[i], RTLD_LAZY))) {
  27. LOG_WARNING("warning: failed to load native library %s",
  28. native_lib_list[i]);
  29. continue;
  30. }
  31. /* lookup get_native_lib func */
  32. get_native_lib_func get_native_lib = dlsym(handle, "get_native_lib");
  33. if (!get_native_lib) {
  34. LOG_WARNING("warning: failed to lookup `get_native_lib` function "
  35. "from native lib %s",
  36. native_lib_list[i]);
  37. dlclose(handle);
  38. continue;
  39. }
  40. n_native_symbols = get_native_lib(&module_name, &native_symbols);
  41. /* register native symbols */
  42. if (!(n_native_symbols > 0 && module_name && native_symbols
  43. && wasm_runtime_register_natives(module_name, native_symbols,
  44. n_native_symbols))) {
  45. LOG_WARNING("warning: failed to register native lib %s",
  46. native_lib_list[i]);
  47. dlclose(handle);
  48. continue;
  49. }
  50. native_handle_list[native_handle_count++] = handle;
  51. }
  52. return native_handle_count;
  53. }
  54. static void
  55. unregister_and_unload_native_libs(uint32 native_lib_count,
  56. void **native_handle_list)
  57. {
  58. uint32 i, n_native_symbols;
  59. NativeSymbol *native_symbols;
  60. char *module_name;
  61. void *handle;
  62. for (i = 0; i < native_lib_count; i++) {
  63. handle = native_handle_list[i];
  64. /* lookup get_native_lib func */
  65. get_native_lib_func get_native_lib = dlsym(handle, "get_native_lib");
  66. if (!get_native_lib) {
  67. LOG_WARNING("warning: failed to lookup `get_native_lib` function "
  68. "from native lib %p",
  69. handle);
  70. continue;
  71. }
  72. n_native_symbols = get_native_lib(&module_name, &native_symbols);
  73. if (n_native_symbols == 0 || module_name == NULL
  74. || native_symbols == NULL) {
  75. LOG_WARNING("warning: get_native_lib returned different values for "
  76. "native lib %p",
  77. handle);
  78. continue;
  79. }
  80. /* unregister native symbols */
  81. if (!wasm_runtime_unregister_natives(module_name, native_symbols)) {
  82. LOG_WARNING("warning: failed to unregister native lib %p", handle);
  83. continue;
  84. }
  85. dlclose(handle);
  86. }
  87. }
  88. #endif
  89. /* clang-format off */
  90. static void
  91. print_help()
  92. {
  93. printf("Usage: wamrc [options] -o output_file wasm_file\n");
  94. printf(" --target=<arch-name> Set the target arch, which has the general format: <arch><sub>\n");
  95. printf(" <arch> = x86_64, i386, aarch64, arm, thumb, xtensa, mips,\n");
  96. printf(" riscv64, riscv32.\n");
  97. printf(" Default is host arch, e.g. x86_64\n");
  98. printf(" <sub> = for ex. on arm or thumb: v5, v6m, v7a, v7m, etc.\n");
  99. printf(" Use --target=help to list supported targets\n");
  100. printf(" --target-abi=<abi> Set the target ABI, e.g. gnu, eabi, gnueabihf, msvc, etc.\n");
  101. printf(" Default is gnu if target isn't riscv64 or riscv32\n");
  102. printf(" For target riscv64 and riscv32, default is lp64d and ilp32d\n");
  103. printf(" Use --target-abi=help to list all the ABI supported\n");
  104. printf(" --cpu=<cpu> Set the target CPU (default: host CPU, e.g. skylake)\n");
  105. printf(" Use --cpu=help to list all the CPU supported\n");
  106. printf(" --cpu-features=<features> Enable or disable the CPU features\n");
  107. printf(" Use +feature to enable a feature, or -feature to disable it\n");
  108. printf(" For example, --cpu-features=+feature1,-feature2\n");
  109. printf(" Use --cpu-features=+help to list all the features supported\n");
  110. printf(" --opt-level=n Set the optimization level (0 to 3, default is 3)\n");
  111. printf(" --size-level=n Set the code size level (0 to 3, default is 3)\n");
  112. printf(" -sgx Generate code for SGX platform (Intel Software Guard Extensions)\n");
  113. printf(" --bounds-checks=1/0 Enable or disable the bounds checks for memory access:\n");
  114. printf(" by default it is disabled in all 64-bit platforms except SGX and\n");
  115. printf(" in these platforms runtime does bounds checks with hardware trap,\n");
  116. printf(" and by default it is enabled in all 32-bit platforms\n");
  117. printf(" CAVEAT: --bounds-checks=0 enables some optimizations\n");
  118. printf(" which make the compiled AOT module incompatible\n");
  119. printf(" with a runtime without the hardware bounds checks.\n");
  120. printf(" --stack-bounds-checks=1/0 Enable or disable the bounds checks for native stack:\n");
  121. printf(" if the option isn't set, the status is same as `--bounds-check`,\n");
  122. printf(" if the option is set:\n");
  123. printf(" (1) it is always enabled when `--bounds-checks` is enabled,\n");
  124. printf(" (2) else it is enabled/disabled according to the option value\n");
  125. printf(" --stack-usage=<file> Generate a stack-usage file.\n");
  126. printf(" Similarly to `clang -fstack-usage`.\n");
  127. printf(" --format=<format> Specifies the format of the output file\n");
  128. printf(" The format supported:\n");
  129. printf(" aot (default) AoT file\n");
  130. printf(" object Native object file\n");
  131. printf(" llvmir-unopt Unoptimized LLVM IR\n");
  132. printf(" llvmir-opt Optimized LLVM IR\n");
  133. printf(" --disable-bulk-memory Disable the MVP bulk memory feature\n");
  134. printf(" --enable-multi-thread Enable multi-thread feature, the dependent features bulk-memory and\n");
  135. printf(" thread-mgr will be enabled automatically\n");
  136. printf(" --enable-tail-call Enable the post-MVP tail call feature\n");
  137. printf(" --disable-simd Disable the post-MVP 128-bit SIMD feature:\n");
  138. printf(" currently 128-bit SIMD is supported for x86-64 and aarch64 targets,\n");
  139. printf(" and by default it is enabled in them and disabled in other targets\n");
  140. printf(" --disable-ref-types Disable the MVP reference types feature\n");
  141. printf(" --disable-aux-stack-check Disable auxiliary stack overflow/underflow check\n");
  142. printf(" --enable-dump-call-stack Enable stack trace feature\n");
  143. printf(" --enable-perf-profiling Enable function performance profiling\n");
  144. printf(" --enable-memory-profiling Enable memory usage profiling\n");
  145. printf(" --xip A shorthand of --enable-indirect-mode --disable-llvm-intrinsics\n");
  146. printf(" --enable-indirect-mode Enable call function through symbol table but not direct call\n");
  147. printf(" --disable-llvm-intrinsics Disable the LLVM built-in intrinsics\n");
  148. printf(" --enable-builtin-intrinsics=<flags>\n");
  149. printf(" Enable the specified built-in intrinsics, it will override the default\n");
  150. printf(" settings. It only takes effect when --disable-llvm-intrinsics is set.\n");
  151. printf(" Available flags: all, i32.common, i64.common, f32.common, f64.common,\n");
  152. printf(" i32.clz, i32.ctz, etc, refer to doc/xip.md for full list\n");
  153. printf(" Use comma to separate, please refer to doc/xip.md for full list.\n");
  154. printf(" --disable-llvm-lto Disable the LLVM link time optimization\n");
  155. printf(" --enable-llvm-pgo Enable LLVM PGO (Profile-Guided Optimization)\n");
  156. printf(" --enable-llvm-passes=<passes>\n");
  157. printf(" Enable the specified LLVM passes, using comma to separate\n");
  158. printf(" --use-prof-file=<file> Use profile file collected by LLVM PGO (Profile-Guided Optimization)\n");
  159. printf(" --enable-segue[=<flags>] Enable using segment register GS as the base address of linear memory,\n");
  160. printf(" only available on linux/linux-sgx x86-64, which may improve performance,\n");
  161. printf(" flags can be: i32.load, i64.load, f32.load, f64.load, v128.load,\n");
  162. printf(" i32.store, i64.store, f32.store, f64.store, v128.store\n");
  163. printf(" Use comma to separate, e.g. --enable-segue=i32.load,i64.store\n");
  164. printf(" and --enable-segue means all flags are added.\n");
  165. printf(" --emit-custom-sections=<section names>\n");
  166. printf(" Emit the specified custom sections to AoT file, using comma to separate\n");
  167. printf(" multiple names, e.g.\n");
  168. printf(" --emit-custom-sections=section1,section2,sectionN\n");
  169. #if BH_HAS_DLFCN
  170. printf(" --native-lib=<lib> Register native libraries to the WASM module, which\n");
  171. printf(" are shared object (.so) files, for example:\n");
  172. printf(" --native-lib=test1.so --native-lib=test2.so\n");
  173. #endif
  174. printf(" -v=n Set log verbose level (0 to 5, default is 2), larger with more log\n");
  175. printf(" --version Show version information\n");
  176. printf("Examples: wamrc -o test.aot test.wasm\n");
  177. printf(" wamrc --target=i386 -o test.aot test.wasm\n");
  178. printf(" wamrc --target=i386 --format=object -o test.o test.wasm\n");
  179. printf(" wamrc --target-abi=help\n");
  180. printf(" wamrc --target=x86_64 --cpu=help\n");
  181. }
  182. /* clang-format on */
  183. #define PRINT_HELP_AND_EXIT() \
  184. do { \
  185. print_help(); \
  186. goto fail0; \
  187. } while (0)
  188. /**
  189. * Split a string into an array of strings
  190. * Returns NULL on failure
  191. * Memory must be freed by caller
  192. * Based on: http://stackoverflow.com/a/11198630/471795
  193. */
  194. static char **
  195. split_string(char *str, int *count, const char *delimer)
  196. {
  197. char **res = NULL, **res1;
  198. char *p;
  199. int idx = 0;
  200. /* split string and append tokens to 'res' */
  201. do {
  202. p = strtok(str, delimer);
  203. str = NULL;
  204. res1 = res;
  205. res = (char **)realloc(res1, sizeof(char *) * (uint32)(idx + 1));
  206. if (res == NULL) {
  207. free(res1);
  208. return NULL;
  209. }
  210. res[idx++] = p;
  211. } while (p);
  212. /**
  213. * Due to the section name,
  214. * res[0] might contain a '\' to indicate a space
  215. * func\name -> func name
  216. */
  217. p = strchr(res[0], '\\');
  218. while (p) {
  219. *p = ' ';
  220. p = strchr(p, '\\');
  221. }
  222. if (count) {
  223. *count = idx - 1;
  224. }
  225. return res;
  226. }
  227. static uint32
  228. resolve_segue_flags(char *str_flags)
  229. {
  230. uint32 segue_flags = 0;
  231. int32 flag_count, i;
  232. char **flag_list;
  233. flag_list = split_string(str_flags, &flag_count, ",");
  234. if (flag_list) {
  235. for (i = 0; i < flag_count; i++) {
  236. if (!strcmp(flag_list[i], "i32.load")) {
  237. segue_flags |= 1 << 0;
  238. }
  239. else if (!strcmp(flag_list[i], "i64.load")) {
  240. segue_flags |= 1 << 1;
  241. }
  242. else if (!strcmp(flag_list[i], "f32.load")) {
  243. segue_flags |= 1 << 2;
  244. }
  245. else if (!strcmp(flag_list[i], "f64.load")) {
  246. segue_flags |= 1 << 3;
  247. }
  248. else if (!strcmp(flag_list[i], "v128.load")) {
  249. segue_flags |= 1 << 4;
  250. }
  251. else if (!strcmp(flag_list[i], "i32.store")) {
  252. segue_flags |= 1 << 8;
  253. }
  254. else if (!strcmp(flag_list[i], "i64.store")) {
  255. segue_flags |= 1 << 9;
  256. }
  257. else if (!strcmp(flag_list[i], "f32.store")) {
  258. segue_flags |= 1 << 10;
  259. }
  260. else if (!strcmp(flag_list[i], "f64.store")) {
  261. segue_flags |= 1 << 11;
  262. }
  263. else if (!strcmp(flag_list[i], "v128.store")) {
  264. segue_flags |= 1 << 12;
  265. }
  266. else {
  267. /* invalid flag */
  268. segue_flags = (uint32)-1;
  269. break;
  270. }
  271. }
  272. free(flag_list);
  273. }
  274. return segue_flags;
  275. }
  276. /* When print help info for target/cpu/target-abi/cpu-features, load this dummy
  277. * wasm file content rather than from an input file, the dummy wasm file content
  278. * is: magic header + version number */
  279. static unsigned char dummy_wasm_file[8] = { 0x00, 0x61, 0x73, 0x6D,
  280. 0x01, 0x00, 0x00, 0x00 };
  281. int
  282. main(int argc, char *argv[])
  283. {
  284. char *wasm_file_name = NULL, *out_file_name = NULL;
  285. uint8 *wasm_file = NULL;
  286. uint32 wasm_file_size;
  287. wasm_module_t wasm_module = NULL;
  288. aot_comp_data_t comp_data = NULL;
  289. aot_comp_context_t comp_ctx = NULL;
  290. RuntimeInitArgs init_args;
  291. AOTCompOption option = { 0 };
  292. char error_buf[128];
  293. int log_verbose_level = 2;
  294. bool sgx_mode = false, size_level_set = false, use_dummy_wasm = false;
  295. int exit_status = EXIT_FAILURE;
  296. #if BH_HAS_DLFCN
  297. const char *native_lib_list[8] = { NULL };
  298. uint32 native_lib_count = 0;
  299. void *native_handle_list[8] = { NULL };
  300. uint32 native_handle_count = 0;
  301. #endif
  302. option.opt_level = 3;
  303. option.size_level = 3;
  304. option.output_format = AOT_FORMAT_FILE;
  305. /* default value, enable or disable depends on the platform */
  306. option.bounds_checks = 2;
  307. /* default value, enable or disable depends on the platform */
  308. option.stack_bounds_checks = 2;
  309. option.enable_simd = true;
  310. option.enable_aux_stack_check = true;
  311. option.enable_bulk_memory = true;
  312. option.enable_ref_types = true;
  313. /* Process options */
  314. for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
  315. if (!strcmp(argv[0], "-o")) {
  316. argc--, argv++;
  317. if (argc < 2)
  318. PRINT_HELP_AND_EXIT();
  319. out_file_name = argv[0];
  320. }
  321. else if (!strncmp(argv[0], "--target=", 9)) {
  322. if (argv[0][9] == '\0')
  323. PRINT_HELP_AND_EXIT();
  324. option.target_arch = argv[0] + 9;
  325. if (!strcmp(option.target_arch, "help")) {
  326. use_dummy_wasm = true;
  327. }
  328. }
  329. else if (!strncmp(argv[0], "--target-abi=", 13)) {
  330. if (argv[0][13] == '\0')
  331. PRINT_HELP_AND_EXIT();
  332. option.target_abi = argv[0] + 13;
  333. if (!strcmp(option.target_abi, "help")) {
  334. use_dummy_wasm = true;
  335. }
  336. }
  337. else if (!strncmp(argv[0], "--cpu=", 6)) {
  338. if (argv[0][6] == '\0')
  339. PRINT_HELP_AND_EXIT();
  340. option.target_cpu = argv[0] + 6;
  341. if (!strcmp(option.target_cpu, "help")) {
  342. use_dummy_wasm = true;
  343. }
  344. }
  345. else if (!strncmp(argv[0], "--cpu-features=", 15)) {
  346. if (argv[0][15] == '\0')
  347. PRINT_HELP_AND_EXIT();
  348. option.cpu_features = argv[0] + 15;
  349. if (!strcmp(option.cpu_features, "+help")) {
  350. use_dummy_wasm = true;
  351. }
  352. }
  353. else if (!strncmp(argv[0], "--opt-level=", 12)) {
  354. if (argv[0][12] == '\0')
  355. PRINT_HELP_AND_EXIT();
  356. option.opt_level = (uint32)atoi(argv[0] + 12);
  357. if (option.opt_level > 3)
  358. option.opt_level = 3;
  359. }
  360. else if (!strncmp(argv[0], "--size-level=", 13)) {
  361. if (argv[0][13] == '\0')
  362. PRINT_HELP_AND_EXIT();
  363. option.size_level = (uint32)atoi(argv[0] + 13);
  364. if (option.size_level > 3)
  365. option.size_level = 3;
  366. size_level_set = true;
  367. }
  368. else if (!strcmp(argv[0], "-sgx")) {
  369. sgx_mode = true;
  370. }
  371. else if (!strncmp(argv[0], "--bounds-checks=", 16)) {
  372. option.bounds_checks = (atoi(argv[0] + 16) == 1) ? 1 : 0;
  373. }
  374. else if (!strncmp(argv[0], "--stack-bounds-checks=", 22)) {
  375. option.stack_bounds_checks = (atoi(argv[0] + 22) == 1) ? 1 : 0;
  376. }
  377. else if (!strncmp(argv[0], "--stack-usage=", 14)) {
  378. option.stack_usage_file = argv[0] + 14;
  379. }
  380. else if (!strncmp(argv[0], "--format=", 9)) {
  381. if (argv[0][9] == '\0')
  382. PRINT_HELP_AND_EXIT();
  383. if (!strcmp(argv[0] + 9, "aot"))
  384. option.output_format = AOT_FORMAT_FILE;
  385. else if (!strcmp(argv[0] + 9, "object"))
  386. option.output_format = AOT_OBJECT_FILE;
  387. else if (!strcmp(argv[0] + 9, "llvmir-unopt"))
  388. option.output_format = AOT_LLVMIR_UNOPT_FILE;
  389. else if (!strcmp(argv[0] + 9, "llvmir-opt"))
  390. option.output_format = AOT_LLVMIR_OPT_FILE;
  391. else {
  392. printf("Invalid format %s.\n", argv[0] + 9);
  393. PRINT_HELP_AND_EXIT();
  394. }
  395. }
  396. else if (!strncmp(argv[0], "-v=", 3)) {
  397. log_verbose_level = atoi(argv[0] + 3);
  398. if (log_verbose_level < 0 || log_verbose_level > 5)
  399. PRINT_HELP_AND_EXIT();
  400. }
  401. else if (!strcmp(argv[0], "--disable-bulk-memory")) {
  402. option.enable_bulk_memory = false;
  403. }
  404. else if (!strcmp(argv[0], "--enable-multi-thread")) {
  405. option.enable_bulk_memory = true;
  406. option.enable_thread_mgr = true;
  407. option.enable_ref_types = false;
  408. }
  409. else if (!strcmp(argv[0], "--enable-tail-call")) {
  410. option.enable_tail_call = true;
  411. }
  412. else if (!strcmp(argv[0], "--enable-simd")) {
  413. /* obsolete option, kept for compatibility */
  414. option.enable_simd = true;
  415. }
  416. else if (!strcmp(argv[0], "--disable-simd")) {
  417. option.enable_simd = false;
  418. }
  419. else if (!strcmp(argv[0], "--disable-ref-types")) {
  420. option.enable_ref_types = false;
  421. }
  422. else if (!strcmp(argv[0], "--disable-aux-stack-check")) {
  423. option.enable_aux_stack_check = false;
  424. }
  425. else if (!strcmp(argv[0], "--enable-dump-call-stack")) {
  426. option.enable_aux_stack_frame = true;
  427. }
  428. else if (!strcmp(argv[0], "--enable-perf-profiling")) {
  429. option.enable_aux_stack_frame = true;
  430. }
  431. else if (!strcmp(argv[0], "--enable-memory-profiling")) {
  432. option.enable_stack_estimation = true;
  433. }
  434. else if (!strcmp(argv[0], "--xip")) {
  435. option.is_indirect_mode = true;
  436. option.disable_llvm_intrinsics = true;
  437. }
  438. else if (!strcmp(argv[0], "--enable-indirect-mode")) {
  439. option.is_indirect_mode = true;
  440. }
  441. else if (!strcmp(argv[0], "--disable-llvm-intrinsics")) {
  442. option.disable_llvm_intrinsics = true;
  443. }
  444. else if (!strncmp(argv[0], "--enable-builtin-intrinsics=", 28)) {
  445. if (argv[0][28] == '\0')
  446. PRINT_HELP_AND_EXIT();
  447. option.builtin_intrinsics = argv[0] + 28;
  448. }
  449. else if (!strcmp(argv[0], "--disable-llvm-lto")) {
  450. option.disable_llvm_lto = true;
  451. }
  452. else if (!strcmp(argv[0], "--enable-llvm-pgo")) {
  453. option.enable_llvm_pgo = true;
  454. }
  455. else if (!strncmp(argv[0], "--enable-llvm-passes=", 21)) {
  456. if (argv[0][21] == '\0')
  457. PRINT_HELP_AND_EXIT();
  458. option.llvm_passes = argv[0] + 21;
  459. }
  460. else if (!strncmp(argv[0], "--use-prof-file=", 16)) {
  461. if (argv[0][16] == '\0')
  462. PRINT_HELP_AND_EXIT();
  463. option.use_prof_file = argv[0] + 16;
  464. }
  465. else if (!strcmp(argv[0], "--enable-segue")) {
  466. /* all flags are enabled */
  467. option.segue_flags = 0x1F1F;
  468. }
  469. else if (!strncmp(argv[0], "--enable-segue=", 15)) {
  470. option.segue_flags = resolve_segue_flags(argv[0] + 15);
  471. if (option.segue_flags == (uint32)-1)
  472. PRINT_HELP_AND_EXIT();
  473. }
  474. else if (!strncmp(argv[0], "--emit-custom-sections=", 23)) {
  475. int len = 0;
  476. if (option.custom_sections) {
  477. free(option.custom_sections);
  478. }
  479. option.custom_sections = split_string(argv[0] + 23, &len, ",");
  480. if (!option.custom_sections) {
  481. printf("Failed to process emit-custom-sections: alloc "
  482. "memory failed\n");
  483. PRINT_HELP_AND_EXIT();
  484. }
  485. option.custom_sections_count = len;
  486. }
  487. #if BH_HAS_DLFCN
  488. else if (!strncmp(argv[0], "--native-lib=", 13)) {
  489. if (argv[0][13] == '\0')
  490. PRINT_HELP_AND_EXIT();
  491. if (native_lib_count >= sizeof(native_lib_list) / sizeof(char *)) {
  492. printf("Only allow max native lib number %d\n",
  493. (int)(sizeof(native_lib_list) / sizeof(char *)));
  494. goto fail0;
  495. }
  496. native_lib_list[native_lib_count++] = argv[0] + 13;
  497. }
  498. #endif
  499. else if (!strncmp(argv[0], "--version", 9)) {
  500. uint32 major, minor, patch;
  501. wasm_runtime_get_version(&major, &minor, &patch);
  502. printf("wamrc %u.%u.%u\n", major, minor, patch);
  503. return 0;
  504. }
  505. else
  506. PRINT_HELP_AND_EXIT();
  507. }
  508. if (!use_dummy_wasm && (argc == 0 || !out_file_name))
  509. PRINT_HELP_AND_EXIT();
  510. if (!size_level_set) {
  511. /**
  512. * Set opt level to 1 by default for Windows and MacOS as
  513. * they can not memory map out 0-2GB memory and might not
  514. * be able to meet the requirements of some AOT relocation
  515. * operations.
  516. */
  517. if (option.target_abi && !strcmp(option.target_abi, "msvc")) {
  518. LOG_VERBOSE("Set size level to 1 for Windows AOT file");
  519. option.size_level = 1;
  520. }
  521. #if defined(_WIN32) || defined(_WIN32_) || defined(__APPLE__) \
  522. || defined(__MACH__)
  523. if (!option.target_abi) {
  524. LOG_VERBOSE("Set size level to 1 for Windows or MacOS AOT file");
  525. option.size_level = 1;
  526. }
  527. #endif
  528. }
  529. if (sgx_mode) {
  530. option.size_level = 1;
  531. option.is_sgx_platform = true;
  532. }
  533. if (!use_dummy_wasm) {
  534. wasm_file_name = argv[0];
  535. if (!strcmp(wasm_file_name, out_file_name)) {
  536. printf("Error: input file and output file are the same");
  537. return -1;
  538. }
  539. }
  540. memset(&init_args, 0, sizeof(RuntimeInitArgs));
  541. init_args.mem_alloc_type = Alloc_With_Allocator;
  542. init_args.mem_alloc_option.allocator.malloc_func = malloc;
  543. init_args.mem_alloc_option.allocator.realloc_func = realloc;
  544. init_args.mem_alloc_option.allocator.free_func = free;
  545. /* initialize runtime environment */
  546. if (!wasm_runtime_full_init(&init_args)) {
  547. printf("Init runtime environment failed.\n");
  548. return -1;
  549. }
  550. bh_log_set_verbose_level(log_verbose_level);
  551. #if BH_HAS_DLFCN
  552. bh_print_time("Begin to load native libs");
  553. native_handle_count = load_and_register_native_libs(
  554. native_lib_list, native_lib_count, native_handle_list);
  555. #endif
  556. bh_print_time("Begin to load wasm file");
  557. if (use_dummy_wasm) {
  558. /* load WASM byte buffer from dummy buffer */
  559. wasm_file_size = sizeof(dummy_wasm_file);
  560. wasm_file = dummy_wasm_file;
  561. }
  562. else {
  563. /* load WASM byte buffer from WASM bin file */
  564. if (!(wasm_file = (uint8 *)bh_read_file_to_buffer(wasm_file_name,
  565. &wasm_file_size)))
  566. goto fail1;
  567. }
  568. if (get_package_type(wasm_file, wasm_file_size) != Wasm_Module_Bytecode) {
  569. printf("Invalid file type: expected wasm file but got other\n");
  570. goto fail2;
  571. }
  572. /* load WASM module */
  573. if (!(wasm_module = wasm_runtime_load(wasm_file, wasm_file_size, error_buf,
  574. sizeof(error_buf)))) {
  575. printf("%s\n", error_buf);
  576. goto fail2;
  577. }
  578. if (!(comp_data = aot_create_comp_data(wasm_module))) {
  579. printf("%s\n", aot_get_last_error());
  580. goto fail3;
  581. }
  582. #if WASM_ENABLE_DEBUG_AOT != 0
  583. if (!create_dwarf_extractor(comp_data, wasm_file_name)) {
  584. printf("%s:create dwarf extractor failed\n", wasm_file_name);
  585. }
  586. #endif
  587. bh_print_time("Begin to create compile context");
  588. if (!(comp_ctx = aot_create_comp_context(comp_data, &option))) {
  589. printf("%s\n", aot_get_last_error());
  590. goto fail4;
  591. }
  592. bh_print_time("Begin to compile");
  593. if (!aot_compile_wasm(comp_ctx)) {
  594. printf("%s\n", aot_get_last_error());
  595. goto fail5;
  596. }
  597. switch (option.output_format) {
  598. case AOT_LLVMIR_UNOPT_FILE:
  599. case AOT_LLVMIR_OPT_FILE:
  600. if (!aot_emit_llvm_file(comp_ctx, out_file_name)) {
  601. printf("%s\n", aot_get_last_error());
  602. goto fail5;
  603. }
  604. break;
  605. case AOT_OBJECT_FILE:
  606. if (!aot_emit_object_file(comp_ctx, out_file_name)) {
  607. printf("%s\n", aot_get_last_error());
  608. goto fail5;
  609. }
  610. break;
  611. case AOT_FORMAT_FILE:
  612. if (!aot_emit_aot_file(comp_ctx, comp_data, out_file_name)) {
  613. printf("%s\n", aot_get_last_error());
  614. goto fail5;
  615. }
  616. break;
  617. default:
  618. break;
  619. }
  620. bh_print_time("Compile end");
  621. printf("Compile success, file %s was generated.\n", out_file_name);
  622. exit_status = EXIT_SUCCESS;
  623. fail5:
  624. /* Destroy compiler context */
  625. aot_destroy_comp_context(comp_ctx);
  626. fail4:
  627. /* Destroy compile data */
  628. aot_destroy_comp_data(comp_data);
  629. fail3:
  630. /* Unload WASM module */
  631. wasm_runtime_unload(wasm_module);
  632. fail2:
  633. /* free the file buffer */
  634. if (!use_dummy_wasm) {
  635. wasm_runtime_free(wasm_file);
  636. }
  637. fail1:
  638. #if BH_HAS_DLFCN
  639. unregister_and_unload_native_libs(native_handle_count, native_handle_list);
  640. #endif
  641. /* Destroy runtime environment */
  642. wasm_runtime_destroy();
  643. fail0:
  644. /* free option.custom_sections */
  645. if (option.custom_sections) {
  646. free(option.custom_sections);
  647. }
  648. bh_print_time("wamrc return");
  649. return exit_status;
  650. }