فهرست منبع

Add "--native-lib=<lib>" option to wamrc (#2342)

Huang Qi 2 سال پیش
والد
کامیت
6a310cc88a
1فایلهای تغییر یافته به همراه126 افزوده شده و 0 حذف شده
  1. 126 0
      wamr-compiler/main.c

+ 126 - 0
wamr-compiler/main.c

@@ -9,6 +9,100 @@
 #include "wasm_export.h"
 #include "aot_export.h"
 
+#if BH_HAS_DLFCN
+#include <dlfcn.h>
+
+typedef uint32 (*get_native_lib_func)(char **p_module_name,
+                                      NativeSymbol **p_native_symbols);
+
+static uint32
+load_and_register_native_libs(const char **native_lib_list,
+                              uint32 native_lib_count,
+                              void **native_handle_list)
+{
+    uint32 i, native_handle_count = 0, n_native_symbols;
+    NativeSymbol *native_symbols;
+    char *module_name;
+    void *handle;
+
+    for (i = 0; i < native_lib_count; i++) {
+        /* open the native library */
+        if (!(handle = dlopen(native_lib_list[i], RTLD_NOW | RTLD_GLOBAL))
+            && !(handle = dlopen(native_lib_list[i], RTLD_LAZY))) {
+            LOG_WARNING("warning: failed to load native library %s",
+                        native_lib_list[i]);
+            continue;
+        }
+
+        /* lookup get_native_lib func */
+        get_native_lib_func get_native_lib = dlsym(handle, "get_native_lib");
+        if (!get_native_lib) {
+            LOG_WARNING("warning: failed to lookup `get_native_lib` function "
+                        "from native lib %s",
+                        native_lib_list[i]);
+            dlclose(handle);
+            continue;
+        }
+
+        n_native_symbols = get_native_lib(&module_name, &native_symbols);
+
+        /* register native symbols */
+        if (!(n_native_symbols > 0 && module_name && native_symbols
+              && wasm_runtime_register_natives(module_name, native_symbols,
+                                               n_native_symbols))) {
+            LOG_WARNING("warning: failed to register native lib %s",
+                        native_lib_list[i]);
+            dlclose(handle);
+            continue;
+        }
+
+        native_handle_list[native_handle_count++] = handle;
+    }
+
+    return native_handle_count;
+}
+
+static void
+unregister_and_unload_native_libs(uint32 native_lib_count,
+                                  void **native_handle_list)
+{
+    uint32 i, n_native_symbols;
+    NativeSymbol *native_symbols;
+    char *module_name;
+    void *handle;
+
+    for (i = 0; i < native_lib_count; i++) {
+        handle = native_handle_list[i];
+
+        /* lookup get_native_lib func */
+        get_native_lib_func get_native_lib = dlsym(handle, "get_native_lib");
+        if (!get_native_lib) {
+            LOG_WARNING("warning: failed to lookup `get_native_lib` function "
+                        "from native lib %p",
+                        handle);
+            continue;
+        }
+
+        n_native_symbols = get_native_lib(&module_name, &native_symbols);
+        if (n_native_symbols == 0 || module_name == NULL
+            || native_symbols == NULL) {
+            LOG_WARNING("warning: get_native_lib returned different values for "
+                        "native lib %p",
+                        handle);
+            continue;
+        }
+
+        /* unregister native symbols */
+        if (!wasm_runtime_unregister_natives(module_name, native_symbols)) {
+            LOG_WARNING("warning: failed to unregister native lib %p", handle);
+            continue;
+        }
+
+        dlclose(handle);
+    }
+}
+#endif
+
 /* clang-format off */
 static void
 print_help()
@@ -83,6 +177,11 @@ print_help()
     printf("                            Emit the specified custom sections to AoT file, using comma to separate\n");
     printf("                            multiple names, e.g.\n");
     printf("                                --emit-custom-sections=section1,section2,sectionN\n");
+#if BH_HAS_DLFCN
+    printf("  --native-lib=<lib>       Register native libraries to the WASM module, which\n");
+    printf("                           are shared object (.so) files, for example:\n");
+    printf("                             --native-lib=test1.so --native-lib=test2.so\n");
+#endif
     printf("  -v=n                      Set log verbose level (0 to 5, default is 2), larger with more log\n");
     printf("  --version                 Show version information\n");
     printf("Examples: wamrc -o test.aot test.wasm\n");
@@ -206,6 +305,12 @@ main(int argc, char *argv[])
     int log_verbose_level = 2;
     bool sgx_mode = false, size_level_set = false;
     int exit_status = EXIT_FAILURE;
+#if BH_HAS_DLFCN
+    const char *native_lib_list[8] = { NULL };
+    uint32 native_lib_count = 0;
+    void *native_handle_list[8] = { NULL };
+    uint32 native_handle_count = 0;
+#endif
 
     option.opt_level = 3;
     option.size_level = 3;
@@ -378,6 +483,18 @@ main(int argc, char *argv[])
 
             option.custom_sections_count = len;
         }
+#if BH_HAS_DLFCN
+        else if (!strncmp(argv[0], "--native-lib=", 13)) {
+            if (argv[0][13] == '\0')
+                PRINT_HELP_AND_EXIT();
+            if (native_lib_count >= sizeof(native_lib_list) / sizeof(char *)) {
+                printf("Only allow max native lib number %d\n",
+                       (int)(sizeof(native_lib_list) / sizeof(char *)));
+                goto fail0;
+            }
+            native_lib_list[native_lib_count++] = argv[0] + 13;
+        }
+#endif
         else if (!strncmp(argv[0], "--version", 9)) {
             uint32 major, minor, patch;
             wasm_runtime_get_version(&major, &minor, &patch);
@@ -438,6 +555,12 @@ main(int argc, char *argv[])
 
     bh_log_set_verbose_level(log_verbose_level);
 
+#if BH_HAS_DLFCN
+    bh_print_time("Begin to load native libs");
+    native_handle_count = load_and_register_native_libs(
+        native_lib_list, native_lib_count, native_handle_list);
+#endif
+
     bh_print_time("Begin to load wasm file");
 
     /* load WASM byte buffer from WASM bin file */
@@ -528,6 +651,9 @@ fail2:
     wasm_runtime_free(wasm_file);
 
 fail1:
+#if BH_HAS_DLFCN
+    unregister_and_unload_native_libs(native_handle_count, native_handle_list);
+#endif
     /* Destroy runtime environment */
     wasm_runtime_destroy();