Index: trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- trunk/src/VBox/Main/Makefile.kmk	(revision 36465)
+++ trunk/src/VBox/Main/Makefile.kmk	(revision 36466)
@@ -245,8 +245,4 @@
 
 VBoxSVC_CXXFLAGS = $(filter-out -Wno-unused,$(TEMPLATE_VBOXMAINEXE_CXXFLAGS))
-## @todo We're disabling optimizations on FreeBSD to work around strange linker
-#        errors in release builds. Figure out why and how to work around it in a
-#        more optimal fashion.
-VBoxSVC_CXXFLAGS.freebsd = -O0
 
 VBoxSVC_INCS = \
Index: trunk/src/VBox/Main/src-server/xpcom/server.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/xpcom/server.cpp	(revision 36465)
+++ trunk/src/VBox/Main/src-server/xpcom/server.cpp	(revision 36466)
@@ -615,5 +615,5 @@
 ////////////////////////////////////////////////////////////////////////////////
 
-typedef NSFactoryDestructorProcPtr NSFactoryConsructorProcPtr;
+typedef NSFactoryDestructorProcPtr NSFactoryConstructorProcPtr;
 
 /**
@@ -621,49 +621,241 @@
  *
  *  nsModuleComponentInfo lacks the factory construction callback, here we add
- *  it. This callback is called by NS_NewGenericFactoryEx() after a
- *  nsGenericFactory instance is successfully created.
+ *  it. This callback is called straight after a nsGenericFactory instance is
+ *  successfully created in RegisterSelfComponents.
  */
-struct nsModuleComponentInfoEx : nsModuleComponentInfo
+struct nsModuleComponentInfoPlusFactoryConstructor
 {
-    nsModuleComponentInfoEx() {}
-    nsModuleComponentInfoEx(int) {}
-
-    nsModuleComponentInfoEx(
-        const char*                                 aDescription,
-        const nsCID&                                aCID,
-        const char*                                 aContractID,
-        NSConstructorProcPtr                        aConstructor,
-        NSRegisterSelfProcPtr                       aRegisterSelfProc,
-        NSUnregisterSelfProcPtr                     aUnregisterSelfProc,
-        NSFactoryDestructorProcPtr                  aFactoryDestructor,
-        NSGetInterfacesProcPtr                      aGetInterfacesProc,
-        NSGetLanguageHelperProcPtr                  aGetLanguageHelperProc,
-        nsIClassInfo **                             aClassInfoGlobal,
-        PRUint32                                    aFlags,
-        NSFactoryConsructorProcPtr                  aFactoryConstructor)
-    {
-        mDescription = aDescription;
-        mCID = aCID;
-        mContractID = aContractID;
-        mConstructor = aConstructor;
-        mRegisterSelfProc = aRegisterSelfProc;
-        mUnregisterSelfProc = aUnregisterSelfProc;
-        mFactoryDestructor = aFactoryDestructor;
-        mGetInterfacesProc = aGetInterfacesProc;
-        mGetLanguageHelperProc = aGetLanguageHelperProc;
-        mClassInfoGlobal = aClassInfoGlobal;
-        mFlags = aFlags;
-        mFactoryConstructor = aFactoryConstructor;
-    }
-
+    /** standard module component information */
+    const nsModuleComponentInfo *mpModuleComponentInfo;
     /** (optional) Factory Construction Callback */
-    NSFactoryConsructorProcPtr mFactoryConstructor;
+    NSFactoryConstructorProcPtr mFactoryConstructor;
 };
 
-////////////////////////////////////////////////////////////////////////////////
-
-static const nsModuleComponentInfoEx components[] =
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Helper function to register self components upon start-up
+ * of the out-of-proc server.
+ */
+static nsresult
+RegisterSelfComponents(nsIComponentRegistrar *registrar,
+                       const nsModuleComponentInfoPlusFactoryConstructor *aComponents,
+                       PRUint32 count)
 {
-    nsModuleComponentInfoEx(
+    nsresult rc = NS_OK;
+    const nsModuleComponentInfoPlusFactoryConstructor *info = aComponents;
+    for (PRUint32 i = 0; i < count && NS_SUCCEEDED(rc); i++, info++)
+    {
+        /* skip components w/o a constructor */
+        if (!info->mpModuleComponentInfo->mConstructor)
+            continue;
+        /* create a new generic factory for a component and register it */
+        nsIGenericFactory *factory;
+        rc = NS_NewGenericFactory(&factory, info->mpModuleComponentInfo);
+        if (NS_SUCCEEDED(rc) && info->mFactoryConstructor)
+        {
+            rc = info->mFactoryConstructor();
+            if (NS_FAILED(rc))
+                NS_RELEASE(factory);
+        }
+        if (NS_SUCCEEDED(rc))
+        {
+            rc = registrar->RegisterFactory(info->mpModuleComponentInfo->mCID,
+                                            info->mpModuleComponentInfo->mDescription,
+                                            info->mpModuleComponentInfo->mContractID,
+                                            factory);
+            NS_RELEASE(factory);
+        }
+    }
+    return rc;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+static ipcIService *gIpcServ = nsnull;
+static const char *g_pszPidFile = NULL;
+
+class ForceQuitEvent : public MyEvent
+{
+    void *handler()
+    {
+        LogFlowFunc(("\n"));
+
+        gKeepRunning = PR_FALSE;
+
+        if (g_pszPidFile)
+            RTFileDelete(g_pszPidFile);
+
+        return NULL;
+    }
+};
+
+static void signal_handler(int sig)
+{
+    if (gEventQ && gKeepRunning)
+    {
+        if (sig == SIGUSR1)
+        {
+            if (gAllowSigUsrQuit)
+            {
+                VirtualBoxClassFactory::MaybeQuitEvent *ev = new VirtualBoxClassFactory::MaybeQuitEvent();
+                ev->postTo(gEventQ);
+            }
+            /* else do nothing */
+        }
+        else
+        {
+            /* post a force quit event to the queue */
+            ForceQuitEvent *ev = new ForceQuitEvent();
+            ev->postTo(gEventQ);
+        }
+    }
+}
+
+static nsresult vboxsvcSpawnDaemonByReExec(const char *pszPath)
+{
+    PRFileDesc *readable = nsnull, *writable = nsnull;
+    PRProcessAttr *attr = nsnull;
+    nsresult rv = NS_ERROR_FAILURE;
+    PRFileDesc *devNull;
+    // The ugly casts are necessary because the PR_CreateProcessDetached has
+    // a const array of writable strings as a parameter. It won't write. */
+    char * const args[] = { (char *)pszPath, (char *)"--auto-shutdown", 0 };
+
+    // Use a pipe to determine when the daemon process is in the position
+    // to actually process requests. The daemon will write "READY" to the pipe.
+    if (PR_CreatePipe(&readable, &writable) != PR_SUCCESS)
+        goto end;
+    PR_SetFDInheritable(writable, PR_TRUE);
+
+    attr = PR_NewProcessAttr();
+    if (!attr)
+        goto end;
+
+    if (PR_ProcessAttrSetInheritableFD(attr, writable, VBOXSVC_STARTUP_PIPE_NAME) != PR_SUCCESS)
+        goto end;
+
+    devNull = PR_Open("/dev/null", PR_RDWR, 0);
+    if (!devNull)
+        goto end;
+
+    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, devNull);
+    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, devNull);
+    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardError, devNull);
+
+    if (PR_CreateProcessDetached(pszPath, args, nsnull, attr) != PR_SUCCESS)
+        goto end;
+
+    // Close /dev/null
+    PR_Close(devNull);
+    // Close the child end of the pipe to make it the only owner of the
+    // file descriptor, so that unexpected closing can be detected.
+    PR_Close(writable);
+    writable = nsnull;
+
+    char msg[10];
+    memset(msg, '\0', sizeof(msg));
+    if (   PR_Read(readable, msg, sizeof(msg)-1) != 5
+        || strcmp(msg, "READY"))
+        goto end;
+
+    rv = NS_OK;
+
+end:
+    if (readable)
+        PR_Close(readable);
+    if (writable)
+        PR_Close(writable);
+    if (attr)
+        PR_DestroyProcessAttr(attr);
+    return rv;
+}
+
+int main(int argc, char **argv)
+{
+    /*
+     * Initialize the VBox runtime without loading
+     * the support driver
+     */
+    RTR3Init();
+
+    static const RTGETOPTDEF s_aOptions[] =
+    {
+        { "--automate",       'a', RTGETOPT_REQ_NOTHING },
+        { "--auto-shutdown",  'A', RTGETOPT_REQ_NOTHING },
+        { "--daemonize",      'd', RTGETOPT_REQ_NOTHING },
+        { "--pidfile",        'p', RTGETOPT_REQ_STRING  },
+    };
+
+    bool            fDaemonize = false;
+    PRFileDesc      *daemon_pipe_wr = nsnull;
+
+    RTGETOPTSTATE   GetOptState;
+    int vrc = RTGetOptInit(&GetOptState, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/);
+    AssertRC(vrc);
+
+    RTGETOPTUNION   ValueUnion;
+    while ((vrc = RTGetOpt(&GetOptState, &ValueUnion)))
+    {
+        switch (vrc)
+        {
+            case 'a':
+            {
+                /* --automate mode means we are started by XPCOM on
+                 * demand. Daemonize ourselves and activate
+                 * auto-shutdown. */
+                gAutoShutdown = true;
+                fDaemonize = true;
+                break;
+            }
+
+            /* Used together with '-P', see below. Internal use only. */
+            case 'A':
+            {
+                gAutoShutdown = true;
+                break;
+            }
+
+            case 'd':
+            {
+                fDaemonize = true;
+                break;
+            }
+
+            case 'p':
+            {
+                g_pszPidFile = ValueUnion.psz;
+                break;
+            }
+
+            case 'h':
+            {
+                RTPrintf("no help\n");
+                return 1;
+            }
+
+            case 'V':
+            {
+                RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
+                return 0;
+            }
+
+            default:
+                return RTGetOptPrintError(vrc, &ValueUnion);
+        }
+    }
+
+    if (fDaemonize)
+    {
+        vboxsvcSpawnDaemonByReExec(argv[0]);
+        exit(126);
+    }
+
+    nsresult    rc;
+
+    daemon_pipe_wr = PR_GetInheritedFD(VBOXSVC_STARTUP_PIPE_NAME);
+    RTEnvUnset("NSPR_INHERIT_FDS");
+
+    const nsModuleComponentInfo VirtualBoxInfo = {
         "VirtualBox component",
         CLSID_VirtualBox,
@@ -676,251 +868,13 @@
         NULL, // language helper
         &NS_CLASSINFO_NAME(VirtualBox),
-        0, // flags
-        VirtualBoxClassFactory::FactoryConstructor // factory constructor function
-    )
-};
-
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- *  Extends NS_NewGenericFactory() by immediately calling
- *  nsModuleComponentInfoEx::mFactoryConstructor before returning to the
- *  caller.
- */
-nsresult
-NS_NewGenericFactoryEx(nsIGenericFactory **result,
-                       const nsModuleComponentInfoEx *info)
-{
-    AssertReturn(result, NS_ERROR_INVALID_POINTER);
-
-    nsresult rv = NS_NewGenericFactory(result, info);
-    if (NS_SUCCEEDED(rv) && info && info->mFactoryConstructor)
-    {
-        rv = info->mFactoryConstructor();
-        if (NS_FAILED(rv))
-            NS_RELEASE(*result);
-    }
-
-    return rv;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Helper function to register self components upon start-up
- * of the out-of-proc server.
- */
-static nsresult
-RegisterSelfComponents(nsIComponentRegistrar *registrar,
-                       const nsModuleComponentInfoEx *aComponents,
-                       PRUint32 count)
-{
-    nsresult rc = NS_OK;
-    const nsModuleComponentInfoEx *info = aComponents;
-    for (PRUint32 i = 0; i < count && NS_SUCCEEDED(rc); i++, info++)
-    {
-        /* skip components w/o a constructor */
-        if (!info->mConstructor)
-            continue;
-        /* create a new generic factory for a component and register it */
-        nsIGenericFactory *factory;
-        rc = NS_NewGenericFactoryEx(&factory, info);
-        if (NS_SUCCEEDED(rc))
-        {
-            rc = registrar->RegisterFactory(info->mCID,
-                                            info->mDescription,
-                                            info->mContractID,
-                                            factory);
-            factory->Release();
-        }
-    }
-    return rc;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-static ipcIService *gIpcServ = nsnull;
-static const char *g_pszPidFile = NULL;
-
-class ForceQuitEvent : public MyEvent
-{
-    void *handler()
-    {
-        LogFlowFunc(("\n"));
-
-        gKeepRunning = PR_FALSE;
-
-        if (g_pszPidFile)
-            RTFileDelete(g_pszPidFile);
-
-        return NULL;
-    }
-};
-
-static void signal_handler(int sig)
-{
-    if (gEventQ && gKeepRunning)
-    {
-        if (sig == SIGUSR1)
-        {
-            if (gAllowSigUsrQuit)
-            {
-                VirtualBoxClassFactory::MaybeQuitEvent *ev = new VirtualBoxClassFactory::MaybeQuitEvent();
-                ev->postTo(gEventQ);
-            }
-            /* else do nothing */
-        }
-        else
-        {
-            /* post a force quit event to the queue */
-            ForceQuitEvent *ev = new ForceQuitEvent();
-            ev->postTo(gEventQ);
-        }
-    }
-}
-
-static nsresult vboxsvcSpawnDaemonByReExec(const char *pszPath)
-{
-    PRFileDesc *readable = nsnull, *writable = nsnull;
-    PRProcessAttr *attr = nsnull;
-    nsresult rv = NS_ERROR_FAILURE;
-    PRFileDesc *devNull;
-    // The ugly casts are necessary because the PR_CreateProcessDetached has
-    // a const array of writable strings as a parameter. It won't write. */
-    char * const args[] = { (char *)pszPath, (char *)"--auto-shutdown", 0 };
-
-    // Use a pipe to determine when the daemon process is in the position
-    // to actually process requests. The daemon will write "READY" to the pipe.
-    if (PR_CreatePipe(&readable, &writable) != PR_SUCCESS)
-        goto end;
-    PR_SetFDInheritable(writable, PR_TRUE);
-
-    attr = PR_NewProcessAttr();
-    if (!attr)
-        goto end;
-
-    if (PR_ProcessAttrSetInheritableFD(attr, writable, VBOXSVC_STARTUP_PIPE_NAME) != PR_SUCCESS)
-        goto end;
-
-    devNull = PR_Open("/dev/null", PR_RDWR, 0);
-    if (!devNull)
-        goto end;
-
-    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, devNull);
-    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, devNull);
-    PR_ProcessAttrSetStdioRedirect(attr, PR_StandardError, devNull);
-
-    if (PR_CreateProcessDetached(pszPath, args, nsnull, attr) != PR_SUCCESS)
-        goto end;
-
-    // Close /dev/null
-    PR_Close(devNull);
-    // Close the child end of the pipe to make it the only owner of the
-    // file descriptor, so that unexpected closing can be detected.
-    PR_Close(writable);
-    writable = nsnull;
-
-    char msg[10];
-    memset(msg, '\0', sizeof(msg));
-    if (   PR_Read(readable, msg, sizeof(msg)-1) != 5
-        || strcmp(msg, "READY"))
-        goto end;
-
-    rv = NS_OK;
-
-end:
-    if (readable)
-        PR_Close(readable);
-    if (writable)
-        PR_Close(writable);
-    if (attr)
-        PR_DestroyProcessAttr(attr);
-    return rv;
-}
-
-int main(int argc, char **argv)
-{
-    /*
-     * Initialize the VBox runtime without loading
-     * the support driver
-     */
-    RTR3Init();
-
-    static const RTGETOPTDEF s_aOptions[] =
-    {
-        { "--automate",       'a', RTGETOPT_REQ_NOTHING },
-        { "--auto-shutdown",  'A', RTGETOPT_REQ_NOTHING },
-        { "--daemonize",      'd', RTGETOPT_REQ_NOTHING },
-        { "--pidfile",        'p', RTGETOPT_REQ_STRING  },
+        0 // flags
     };
 
-    bool            fDaemonize = false;
-    PRFileDesc      *daemon_pipe_wr = nsnull;
-
-    RTGETOPTSTATE   GetOptState;
-    int vrc = RTGetOptInit(&GetOptState, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0 /*fFlags*/);
-    AssertRC(vrc);
-
-    RTGETOPTUNION   ValueUnion;
-    while ((vrc = RTGetOpt(&GetOptState, &ValueUnion)))
-    {
-        switch (vrc)
-        {
-            case 'a':
-            {
-                /* --automate mode means we are started by XPCOM on
-                 * demand. Daemonize ourselves and activate
-                 * auto-shutdown. */
-                gAutoShutdown = true;
-                fDaemonize = true;
-                break;
-            }
-
-            /* Used together with '-P', see below. Internal use only. */
-            case 'A':
-            {
-                gAutoShutdown = true;
-                break;
-            }
-
-            case 'd':
-            {
-                fDaemonize = true;
-                break;
-            }
-
-            case 'p':
-            {
-                g_pszPidFile = ValueUnion.psz;
-                break;
-            }
-
-            case 'h':
-            {
-                RTPrintf("no help\n");
-                return 1;
-            }
-
-            case 'V':
-            {
-                RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
-                return 0;
-            }
-
-            default:
-                return RTGetOptPrintError(vrc, &ValueUnion);
-        }
-    }
-
-    if (fDaemonize)
-    {
-        vboxsvcSpawnDaemonByReExec(argv[0]);
-        exit(126);
-    }
-
-    nsresult    rc;
-
-    daemon_pipe_wr = PR_GetInheritedFD(VBOXSVC_STARTUP_PIPE_NAME);
-    RTEnvUnset("NSPR_INHERIT_FDS");
+    const nsModuleComponentInfoPlusFactoryConstructor components[] = {
+        {
+            &VirtualBoxInfo,
+            VirtualBoxClassFactory::FactoryConstructor // factory constructor function
+        }
+    };
 
     do
@@ -943,5 +897,5 @@
         registrar->AutoRegister(nsnull);
         rc = RegisterSelfComponents(registrar, components,
-                                    NS_ARRAY_LENGTH (components));
+                                    NS_ARRAY_LENGTH(components));
         if (NS_FAILED(rc))
         {
