Check plugins directory names for unsupported capability
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 10 Jan 2010 10:36:55 +0000 (12:36 +0200)
committerRémi Denis-Courmont <remi@remlab.net>
Sun, 10 Jan 2010 10:43:49 +0000 (12:43 +0200)
src/libvlc.h
src/misc/cpu.c
src/modules/modules.c

index e60f711..ced230e 100644 (file)
@@ -79,6 +79,7 @@ void vlc_assert_locked (vlc_mutex_t *);
  */
 extern uint32_t cpu_flags;
 uint32_t CPUCapabilities( void );
+bool vlc_CPU_CheckPluginDir (const char *name);
 
 /*
  * Message/logging stuff
index 6c979fd..d1b9324 100644 (file)
@@ -296,6 +296,48 @@ unsigned vlc_CPU (void)
     return cpu_flags;
 }
 
+const struct
+{
+    uint32_t value;
+    char name[12];
+} cap_dirs[] = {
+#if defined ( __i386__ ) || defined ( __x86_64__ )
+    { CPU_CAPABILITY_MMX,     "mmx" },
+    { CPU_CAPABILITY_MMXEXT,  "mmxext" },
+    { CPU_CAPABILITY_3DNOW,   "3dnow" },
+    { CPU_CAPABILITY_SSE,     "sse" },
+#endif
+#if defined (__ppc__) || defined (__ppc64__) || defined (__powerpc__)
+    { CPU_CAPABILITY_ALTIVEC, "altivec" },
+#endif
+#if defined (__arm__)
+    { CPU_CAPABILITY_NEON,    "arm_neon" },
+#endif
+};
+
+/**
+ * Check if a directory name contains usable plugins w.r.t. the hardware
+ * capabilities. Loading a plugin when the hardware has insufficient
+ * capabilities may lead to illegal instructions (SIGILL) and must be avoided.
+ *
+ * @param name the name of the directory (<b>not</b> the path)
+ *
+ * @return true if the hardware has sufficient capabilities or the directory
+ * does not require any special capability; false if the running hardware has
+ * insufficient capabilities.
+ */
+bool vlc_CPU_CheckPluginDir (const char *name)
+{
+    const unsigned flags = vlc_CPU ();
+    for (size_t i = 0; i < sizeof (cap_dirs) / sizeof (cap_dirs[0]); i++)
+    {
+        if (strcmp (name, cap_dirs[i].name))
+            continue;
+        return (flags & cap_dirs[i].value) != 0;
+    }
+    return true;
+}
+
 static vlc_memcpy_t pf_vlc_memcpy = memcpy;
 static vlc_memset_t pf_vlc_memset = memset;
 
index cdd2630..ec4fa31 100644 (file)
@@ -906,7 +906,9 @@ static void AllocatePluginDir( vlc_object_t *p_this, module_bank_t *p_bank,
             break;
 
         /* Skip ".", ".." */
-        if (!strcmp (file, ".") || !strcmp (file, ".."))
+        if (!strcmp (file, ".") || !strcmp (file, "..")
+        /* Skip directories for unsupported optimizations */
+         || !vlc_CPU_CheckPluginDir (file))
         {
             free (file);
             continue;