Bug 1541792 - Replace linker magic with manual component registration. r=froydnj
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 05 Apr 2019 02:30:56 +0000
changeset 468491 60669a841a87644ba9b2f4d9f17f225e2eca0980
parent 468490 0523ad54267a92d45bcee3986d09b3cdb5954504
child 468492 63d759f0f211d05de7d933b8aa15836ceac6e4b2
push id82622
push usermh@glandium.org
push dateTue, 09 Apr 2019 06:39:21 +0000
treeherderautoland@60669a841a87 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1541792, 938437, 1524687
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1541792 - Replace linker magic with manual component registration. r=froydnj Before bug 938437, we had a rather large and error-prone nsStaticXULComponents.cpp used to register all modules. That was replaced with clever use of the linker, which allowed to avoid the mess that maintaining that file was. Fast forward to now, where after bug 1524687 and other work that preceded it, we have a much smaller number of remaining static xpcom components, registered via this linker hack, and don't expect to add any new ones. The list should eventually go down to zero. Within that context, it seems to be the right time to get rid of the magic, and with it the problems it causes on its own. Some of those components could probably be trivially be converted to static registration via .conf files, but I didn't want to deal with the possible need to increase the number of dummy modules in XPCOMInit.cpp. They can still be converted as a followup. Differential Revision: https://phabricator.services.mozilla.com/D26076
dom/media/webspeech/synth/android/AndroidSpeechModule.cpp
dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerModule.cpp
dom/media/webspeech/synth/windows/SapiModule.cpp
dom/power/PowerManagerService.cpp
layout/build/nsLayoutModule.cpp
layout/tools/layout-debug/src/nsDebugFactory.cpp
mobile/android/components/build/nsBrowserModule.cpp
netwerk/build/nsNetModule.cpp
parser/htmlparser/nsParserModule.cpp
python/mozbuild/mozbuild/action/check_binary.py
security/manager/ssl/LocalCertService.cpp
toolkit/components/kvstore/nsKeyValueModule.cpp
toolkit/library/StaticXULComponents.ld
toolkit/library/moz.build
toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp
toolkit/system/osxproxy/nsOSXSystemProxySettings.mm
toolkit/system/windowsDHCPClient/nsWindowsDHCPClient.cpp
toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsEmbeddingModule.cpp
tools/code-coverage/nsCodeCoverageFactory.cpp
widget/android/nsWidgetFactory.cpp
widget/cocoa/nsWidgetFactory.mm
widget/nsContentProcessWidgetFactory.cpp
widget/uikit/nsWidgetFactory.mm
xpcom/build/XPCOMInit.cpp
xpcom/components/Module.h
xpcom/components/moz.build
xpcom/components/nsComponentManager.cpp
--- a/dom/media/webspeech/synth/android/AndroidSpeechModule.cpp
+++ b/dom/media/webspeech/synth/android/AndroidSpeechModule.cpp
@@ -33,19 +33,17 @@ static const mozilla::Module::CIDEntry k
 static const mozilla::Module::ContractIDEntry kContracts[] = {
     {ANDROIDSPEECHSERVICE_CONTRACTID, &kANDROIDSPEECHSERVICE_CID}, {nullptr}};
 
 static const mozilla::Module::CategoryEntry kCategories[] = {
     {"speech-synth-started", "Android Speech Synth",
      ANDROIDSPEECHSERVICE_CONTRACTID},
     {nullptr}};
 
-static const mozilla::Module kModule = {
+extern const mozilla::Module kSpeechSynthModule = {
     mozilla::Module::kVersion,
     kCIDs,
     kContracts,
     kCategories,
     nullptr,
     nullptr,
     nullptr,
 };
-
-NSMODULE_DEFN(androidspeechsynth) = &kModule;
--- a/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerModule.cpp
+++ b/dom/media/webspeech/synth/cocoa/OSXSpeechSynthesizerModule.cpp
@@ -41,17 +41,16 @@ static const mozilla::Module::CategoryEn
     {"speech-synth-started", "OSX Speech Synth",
      OSXSPEECHSYNTHESIZERSERVICE_CONTRACTID},
     {nullptr}};
 
 static void UnloadOSXSpeechSynthesizerModule() {
   OSXSpeechSynthesizerService::Shutdown();
 }
 
-static const mozilla::Module kModule = {mozilla::Module::kVersion,
-                                        kCIDs,
-                                        kContracts,
-                                        kCategories,
-                                        nullptr,
-                                        nullptr,
-                                        UnloadOSXSpeechSynthesizerModule};
-
-NSMODULE_DEFN(osxsynth) = &kModule;
+extern const mozilla::Module kSpeechSynthModule = {
+    mozilla::Module::kVersion,
+    kCIDs,
+    kContracts,
+    kCategories,
+    nullptr,
+    nullptr,
+    UnloadOSXSpeechSynthesizerModule};
--- a/dom/media/webspeech/synth/windows/SapiModule.cpp
+++ b/dom/media/webspeech/synth/windows/SapiModule.cpp
@@ -34,13 +34,11 @@ static const mozilla::Module::ContractID
     {SAPISERVICE_CONTRACTID, &kSAPISERVICE_CID}, {nullptr}};
 
 static const mozilla::Module::CategoryEntry kCategories[] = {
     {"speech-synth-started", "Sapi Speech Synth", SAPISERVICE_CONTRACTID},
     {nullptr}};
 
 static void UnloadSapiModule() { SapiService::Shutdown(); }
 
-static const mozilla::Module kModule = {
+extern const mozilla::Module kSpeechSynthModule = {
     mozilla::Module::kVersion, kCIDs, kContracts, kCategories, nullptr, nullptr,
     UnloadSapiModule};
-
-NSMODULE_DEFN(synthsapi) = &kModule;
--- a/dom/power/PowerManagerService.cpp
+++ b/dom/power/PowerManagerService.cpp
@@ -168,19 +168,17 @@ static const mozilla::Module::ContractID
     // clang-format off
   { POWERMANAGERSERVICE_CONTRACTID, &kNS_POWERMANAGERSERVICE_CID, mozilla::Module::ALLOW_IN_GPU_AND_SOCKET_PROCESS },
   { nullptr }
     // clang-format on
 };
 
 // We mark the power module as being available in the GPU process because the
 // appshell depends on the power manager service.
-static const mozilla::Module kPowerManagerModule = {
+extern const mozilla::Module kPowerManagerModule = {
     mozilla::Module::kVersion,
     kPowerManagerCIDs,
     kPowerManagerContracts,
     nullptr,
     nullptr,
     nullptr,
     nullptr,
     mozilla::Module::ALLOW_IN_GPU_AND_SOCKET_PROCESS};
-
-NSMODULE_DEFN(nsPowerManagerModule) = &kPowerManagerModule;
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -265,17 +265,15 @@ void nsLayoutModuleDtor() {
   mozilla::image::ShutdownModule();
   gfxPlatform::Shutdown();
   gfx::gfxVars::Shutdown();
 
   nsScriptSecurityManager::Shutdown();
   xpcModuleDtor();
 }
 
-static const mozilla::Module kLayoutModule = {mozilla::Module::kVersion,
+extern const mozilla::Module kLayoutModule = {mozilla::Module::kVersion,
                                               nullptr,
                                               nullptr,
                                               kLayoutCategories,
                                               nullptr,
                                               nullptr,
                                               nullptr};
-
-NSMODULE_DEFN(nsLayoutModule) = &kLayoutModule;
--- a/layout/tools/layout-debug/src/nsDebugFactory.cpp
+++ b/layout/tools/layout-debug/src/nsDebugFactory.cpp
@@ -30,13 +30,11 @@ static const mozilla::Module::ContractID
      &kNS_LAYOUTDEBUGCLH_CID},
     {nullptr}};
 
 static const mozilla::Module::CategoryEntry kLayoutDebugCategories[] = {
     {"command-line-handler", "m-layoutdebug",
      "@mozilla.org/commandlinehandler/general-startup;1?type=layoutdebug"},
     {nullptr}};
 
-static const mozilla::Module kLayoutDebugModule = {
+extern const mozilla::Module kLayoutDebugModule = {
     mozilla::Module::kVersion, kLayoutDebugCIDs, kLayoutDebugContracts,
     kLayoutDebugCategories};
-
-NSMODULE_DEFN(nsLayoutDebugModule) = &kLayoutDebugModule;
--- a/mobile/android/components/build/nsBrowserModule.cpp
+++ b/mobile/android/components/build/nsBrowserModule.cpp
@@ -42,12 +42,10 @@ static const mozilla::Module::CIDEntry k
 
 static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
     {nsShellService_ContractID, &knsShellService_CID},
 #ifdef MOZ_ANDROID_HISTORY
     {NS_IHISTORY_CONTRACTID, &kNS_ANDROIDHISTORY_CID},
 #endif
     {nullptr}};
 
-static const mozilla::Module kBrowserModule = {mozilla::Module::kVersion,
+extern const mozilla::Module kBrowserModule = {mozilla::Module::kVersion,
                                                kBrowserCIDs, kBrowserContracts};
-
-NSMODULE_DEFN(nsBrowserCompsModule) = &kBrowserModule;
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -344,19 +344,17 @@ void nsNetShutdown() {
   nsAuthGSSAPI::Shutdown();
 
   delete gNetSniffers;
   gNetSniffers = nullptr;
   delete gDataSniffers;
   gDataSniffers = nullptr;
 }
 
-static const mozilla::Module kNeckoModule = {
+extern const mozilla::Module kNeckoModule = {
     mozilla::Module::kVersion,
     nullptr,
     nullptr,
     kNeckoCategories,
     nullptr,
     nullptr,
     nullptr,
     mozilla::Module::ALLOW_IN_SOCKET_PROCESS};
-
-NSMODULE_DEFN(necko) = &kNeckoModule;
--- a/parser/htmlparser/nsParserModule.cpp
+++ b/parser/htmlparser/nsParserModule.cpp
@@ -26,17 +26,15 @@ static nsresult Initialize() {
   nsHTMLTags::TestTagTable();
 #endif
 
   return rv;
 }
 
 static void Shutdown() { nsHTMLTags::ReleaseTable(); }
 
-static mozilla::Module kParserModule = {mozilla::Module::kVersion,
-                                        kParserCIDs,
-                                        nullptr,
-                                        nullptr,
-                                        nullptr,
-                                        Initialize,
-                                        Shutdown};
-
-NSMODULE_DEFN(nsParserModule) = &kParserModule;
+extern const mozilla::Module kParserModule = {mozilla::Module::kVersion,
+                                              kParserCIDs,
+                                              nullptr,
+                                              nullptr,
+                                              nullptr,
+                                              Initialize,
+                                              Shutdown};
--- a/python/mozbuild/mozbuild/action/check_binary.py
+++ b/python/mozbuild/mozbuild/action/check_binary.py
@@ -209,83 +209,16 @@ def ishex(s):
         return False
 
 
 def is_libxul(binary):
     basename = os.path.basename(binary).lower()
     return 'xul' in basename
 
 
-def check_nsmodules(target, binary):
-    if target is HOST or not is_libxul(binary):
-        raise Skip()
-    symbols = []
-    for sym in iter_symbols(binary):
-        if sym['addr'] == 0:
-            continue
-        name = sym['name']
-        # NSModules symbols end with _NSModule or _NSModuleE when C++-mangled.
-        if name.endswith(('_NSModule', '_NSModuleE')):
-            # We don't have a valid size in the symbol list for macho and coff.
-            # Use our guesstimate.
-            size = sym['size'] or GUESSED_NSMODULE_SIZE
-            symbols.append((sym['addr'], size, name))
-        elif name in ('__start_kPStaticModules', '__stop_kPStaticModules'):
-            # For coff, these symbols have a size.
-            if get_type(binary) not in (ELF, MACHO):
-                size = GUESSED_NSMODULE_SIZE
-            else:
-                size = 0
-            symbols.append((sym['addr'], size, name))
-    if not symbols:
-        raise RuntimeError('Could not find NSModules')
-
-    def print_symbols(symbols):
-        for addr, size, sym in symbols:
-            print('%x %d %s' % (addr, size, sym))
-
-    symbols = sorted(symbols)
-    next_addr = None
-    # MSVC linker, when doing incremental linking, adds padding when
-    # merging sections. Allow there to be more space between the NSModule
-    # symbols, as long as they are in the right order.
-    test_msvc = (buildconfig.substs.get('CC_TYPE') == 'clang-cl' and \
-        buildconfig.substs.get('DEVELOPER_OPTIONS'))
-    test_clang = (buildconfig.substs.get('CC_TYPE') == 'clang' and \
-        buildconfig.substs.get('OS_ARCH') == 'WINNT')
-    if test_msvc or test_clang:
-        sym_cmp = lambda guessed, actual: guessed <= actual
-    else:
-        sym_cmp = lambda guessed, actual: guessed == actual
-
-    for addr, size, sym in symbols:
-        if next_addr is not None and not sym_cmp(next_addr, addr):
-            print_symbols(symbols)
-            raise RuntimeError('NSModules are not adjacent')
-        next_addr = addr + size
-
-    # The mac linker doesn't emit the start/stop symbols in the symbol table.
-    # We'll just assume it did the job correctly.
-    if get_type(binary) == MACHO:
-        return
-
-    first = symbols[0][2]
-    last = symbols[-1][2]
-    # On some platforms, there are extra underscores on symbol names.
-    if first.lstrip('_') != 'start_kPStaticModules' or \
-            last.lstrip('_') != 'stop_kPStaticModules':
-        print_symbols(symbols)
-        syms = set(sym for add, size, sym in symbols)
-        if 'start_kPStaticModules' not in syms:
-            raise RuntimeError('Could not find start_kPStaticModules symbol')
-        if 'stop_kPStaticModules' not in syms:
-            raise RuntimeError('Could not find stop_kPStaticModules symbol')
-        raise RuntimeError('NSModules are not ordered appropriately')
-
-
 def check_pt_load(target, binary):
     if target is HOST or get_type(binary) != ELF or not is_libxul(binary):
         raise Skip()
     count = 0
     for line in get_output(target['readelf'], '-l', binary):
         data = line.split()
         if data and data[0] == 'LOAD':
             count += 1
@@ -366,18 +299,16 @@ def checks(target, binary):
         checks.append(check_glibc)
 
     # Disabled for local builds because of readelf performance: See bug 1472496
     if not buildconfig.substs.get('DEVELOPER_OPTIONS'):
         checks.append(check_textrel)
         checks.append(check_pt_load)
         checks.append(check_mozglue_order)
 
-    checks.append(check_nsmodules)
-
     retcode = 0
     basename = os.path.basename(binary)
     for c in checks:
         try:
             name = c.__name__
             c(target, binary)
             if buildconfig.substs.get('MOZ_AUTOMATION'):
                 print('TEST-PASS | {} | {}'.format(name, basename))
--- a/security/manager/ssl/LocalCertService.cpp
+++ b/security/manager/ssl/LocalCertService.cpp
@@ -463,14 +463,12 @@ NS_DEFINE_NAMED_CID(LOCALCERTSERVICE_CID
 
 static const Module::CIDEntry kLocalCertServiceCIDs[] = {
     {&kLOCALCERTSERVICE_CID, false, nullptr, LocalCertServiceConstructor},
     {nullptr}};
 
 static const Module::ContractIDEntry kLocalCertServiceContracts[] = {
     {LOCALCERTSERVICE_CONTRACTID, &kLOCALCERTSERVICE_CID}, {nullptr}};
 
-static const Module kLocalCertServiceModule = {
+extern const Module kLocalCertServiceModule = {
     Module::kVersion, kLocalCertServiceCIDs, kLocalCertServiceContracts};
 
-NSMODULE_DEFN(LocalCertServiceModule) = &kLocalCertServiceModule;
-
 }  // namespace mozilla
--- a/toolkit/components/kvstore/nsKeyValueModule.cpp
+++ b/toolkit/components/kvstore/nsKeyValueModule.cpp
@@ -17,12 +17,10 @@ NS_DEFINE_NAMED_CID(NS_KEY_VALUE_SERVICE
 
 const mozilla::Module::CIDEntry kKeyValueCIDs[] = {
     {&kNS_KEY_VALUE_SERVICE_CID, false, nullptr, nsKeyValueServiceConstructor},
     {nullptr}};
 
 const mozilla::Module::ContractIDEntry kKeyValueContracts[] = {
     {NS_KEY_VALUE_SERVICE_CONTRACTID, &kNS_KEY_VALUE_SERVICE_CID}, {nullptr}};
 
-const mozilla::Module kKeyValueModule = {
+extern const mozilla::Module kKeyValueModule = {
     mozilla::Module::kVersion, kKeyValueCIDs, kKeyValueContracts, nullptr};
-
-NSMODULE_DEFN(nsKeyValueModule) = &kKeyValueModule;
deleted file mode 100644
--- a/toolkit/library/StaticXULComponents.ld
+++ /dev/null
@@ -1,7 +0,0 @@
-SECTIONS {
-  .data.rel.ro : {
-    PROVIDE_HIDDEN(__start_kPStaticModules = .);
-    *(kPStaticModules)
-    PROVIDE_HIDDEN(__stop_kPStaticModules = .);
-  }
-}
--- a/toolkit/library/moz.build
+++ b/toolkit/library/moz.build
@@ -53,27 +53,16 @@ def Libxul(name, output_category=None):
             '/xpcom/base',
         ]
         # config/version.mk says $(srcdir)/$(RCINCLUDE), and this needs to
         # be valid in both toolkit/library and toolkit/library/gtest.
         # Eventually, the make backend would do its own path canonicalization
         # and config/version.mk would lift the $(srcdir)
         RCINCLUDE = '$(DEPTH)/toolkit/library/xulrunner.rc'
 
-    # BFD ld doesn't create multiple PT_LOADs as usual when an unknown section
-    # exists. Using an implicit linker script to make it fold that section in
-    # .data.rel.ro makes it create multiple PT_LOADs. That implicit linker
-    # script however makes gold misbehave, first because it doesn't like that
-    # the linker script is given after crtbegin.o, and even past that, replaces
-    # the default section rules with those from the script instead of
-    # supplementing them. Which leads to a lib with a huge load of sections.
-    if CONFIG['OS_TARGET'] not in ('OpenBSD', 'WINNT') and \
-            CONFIG['LINKER_KIND'] == 'bfd':
-        LDFLAGS += [TOPSRCDIR + '/toolkit/library/StaticXULComponents.ld']
-
     Libxul_defines()
 
     if CONFIG['MOZ_NEEDS_LIBATOMIC']:
         OS_LIBS += ['atomic']
 
     # TouchBar-related classes are only available in the 10.12.2 SDK and later.
     # We need to weak link these classes until we've upgraded our SDK to at
     # least 10.12.2.
--- a/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp
+++ b/toolkit/system/androidproxy/nsAndroidSystemProxySettings.cpp
@@ -67,12 +67,10 @@ static const mozilla::Module::CIDEntry k
     {&kNS_ANDROIDSYSTEMPROXYSERVICE_CID, false, nullptr,
      nsAndroidSystemProxySettingsConstructor},
     {nullptr}};
 
 static const mozilla::Module::ContractIDEntry kSysProxyContracts[] = {
     {NS_SYSTEMPROXYSETTINGS_CONTRACTID, &kNS_ANDROIDSYSTEMPROXYSERVICE_CID},
     {nullptr}};
 
-static const mozilla::Module kSysProxyModule = {
+extern const mozilla::Module kSysProxyModule = {
     mozilla::Module::kVersion, kSysProxyCIDs, kSysProxyContracts};
-
-NSMODULE_DEFN(nsAndroidProxyModule) = &kSysProxyModule;
--- a/toolkit/system/osxproxy/nsOSXSystemProxySettings.mm
+++ b/toolkit/system/osxproxy/nsOSXSystemProxySettings.mm
@@ -283,12 +283,10 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsOS
 NS_DEFINE_NAMED_CID(NS_OSXSYSTEMPROXYSERVICE_CID);
 
 static const mozilla::Module::CIDEntry kOSXSysProxyCIDs[] = {
     {&kNS_OSXSYSTEMPROXYSERVICE_CID, false, NULL, nsOSXSystemProxySettingsConstructor}, {NULL}};
 
 static const mozilla::Module::ContractIDEntry kOSXSysProxyContracts[] = {
     {NS_SYSTEMPROXYSETTINGS_CONTRACTID, &kNS_OSXSYSTEMPROXYSERVICE_CID}, {NULL}};
 
-static const mozilla::Module kOSXSysProxyModule = {mozilla::Module::kVersion, kOSXSysProxyCIDs,
-                                                   kOSXSysProxyContracts};
-
-NSMODULE_DEFN(nsOSXProxyModule) = &kOSXSysProxyModule;
+extern const mozilla::Module kSysProxyModule = {mozilla::Module::kVersion, kOSXSysProxyCIDs,
+                                                kOSXSysProxyContracts};
--- a/toolkit/system/windowsDHCPClient/nsWindowsDHCPClient.cpp
+++ b/toolkit/system/windowsDHCPClient/nsWindowsDHCPClient.cpp
@@ -87,17 +87,15 @@ NS_DEFINE_NAMED_CID(NS_WINDOWSDHCPCLIENT
 static const mozilla::Module::CIDEntry kSysDHCPClientCIDs[] = {
     {&kNS_WINDOWSDHCPCLIENTSERVICE_CID, false, nullptr,
      nsWindowsDHCPClientConstructor},
     {nullptr}};
 
 static const mozilla::Module::ContractIDEntry kSysDHCPClientContracts[] = {
     {NS_DHCPCLIENT_CONTRACTID, &kNS_WINDOWSDHCPCLIENTSERVICE_CID}, {nullptr}};
 
-static const mozilla::Module kSysDHCPClientModule = {
+extern const mozilla::Module kSysDHCPClientModule = {
     mozilla::Module::kVersion, kSysDHCPClientCIDs, kSysDHCPClientContracts};
 
-NSMODULE_DEFN(nsDHCPClientModule) = &kSysDHCPClientModule;
-
 }  // namespace windowsDHCPClient
 }  // namespace system
 }  // namespace toolkit
 }  // namespace mozilla
--- a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
+++ b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp
@@ -262,12 +262,10 @@ static const mozilla::Module::CIDEntry k
     {&kNS_WINDOWSSYSTEMPROXYSERVICE_CID, false, nullptr,
      nsWindowsSystemProxySettingsConstructor},
     {nullptr}};
 
 static const mozilla::Module::ContractIDEntry kSysProxyContracts[] = {
     {NS_SYSTEMPROXYSETTINGS_CONTRACTID, &kNS_WINDOWSSYSTEMPROXYSERVICE_CID},
     {nullptr}};
 
-static const mozilla::Module kSysProxyModule = {
+extern const mozilla::Module kSysProxyModule = {
     mozilla::Module::kVersion, kSysProxyCIDs, kSysProxyContracts};
-
-NSMODULE_DEFN(nsWindowsProxyModule) = &kSysProxyModule;
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -1278,21 +1278,19 @@ static const mozilla::Module::ContractID
     {XULAPPINFO_SERVICE_CONTRACTID, &kAPPINFO_CID},
     {XULRUNTIME_SERVICE_CONTRACTID, &kAPPINFO_CID},
 #ifdef MOZ_CRASHREPORTER
     {NS_CRASHREPORTER_CONTRACTID, &kAPPINFO_CID},
 #endif  // MOZ_CRASHREPORTER
     {NS_PROFILESERVICE_CONTRACTID, &kProfileServiceCID},
     {nullptr}};
 
-static const mozilla::Module kXREModule = {mozilla::Module::kVersion, kXRECIDs,
+extern const mozilla::Module kXREModule = {mozilla::Module::kVersion, kXRECIDs,
                                            kXREContracts};
 
-NSMODULE_DEFN(Apprunner) = &kXREModule;
-
 nsresult ScopedXPCOMStartup::Initialize() {
   NS_ASSERTION(gDirServiceProvider, "Should not get here!");
 
   nsresult rv;
 
   rv = NS_InitXPCOM(&mServiceManager, gDirServiceProvider->GetAppDir(),
                     gDirServiceProvider);
   if (NS_FAILED(rv)) {
--- a/toolkit/xre/nsEmbeddingModule.cpp
+++ b/toolkit/xre/nsEmbeddingModule.cpp
@@ -34,12 +34,10 @@ static const mozilla::Module::CIDEntry k
     {nullptr}};
 
 static const mozilla::Module::ContractIDEntry kEmbeddingContracts[] = {
 #if defined(MOZ_XUL) && defined(NS_PRINTING)
     {NS_PRINTINGPROMPTSERVICE_CONTRACTID, &kNS_PRINTINGPROMPTSERVICE_CID},
 #endif
     {nullptr}};
 
-static const mozilla::Module kEmbeddingModule = {
+extern const mozilla::Module kEmbeddingModule = {
     mozilla::Module::kVersion, kEmbeddingCIDs, kEmbeddingContracts};
-
-NSMODULE_DEFN(embedcomponents) = &kEmbeddingModule;
--- a/tools/code-coverage/nsCodeCoverageFactory.cpp
+++ b/tools/code-coverage/nsCodeCoverageFactory.cpp
@@ -13,12 +13,10 @@ NS_DEFINE_NAMED_CID(NS_CODECOVERAGE_CID)
 
 static const mozilla::Module::CIDEntry kCodeCoverageCIDs[] = {
     {&kNS_CODECOVERAGE_CID, false, nullptr, nsCodeCoverageConstructor},
     {nullptr}};
 
 static const mozilla::Module::ContractIDEntry kCodeCoverageContracts[] = {
     {"@mozilla.org/tools/code-coverage;1", &kNS_CODECOVERAGE_CID}, {nullptr}};
 
-static const mozilla::Module kCodeCoverageModule = {
+extern const mozilla::Module kCodeCoverageModule = {
     mozilla::Module::kVersion, kCodeCoverageCIDs, kCodeCoverageContracts};
-
-NSMODULE_DEFN(nsCodeCoverageModule) = &kCodeCoverageModule;
--- a/widget/android/nsWidgetFactory.cpp
+++ b/widget/android/nsWidgetFactory.cpp
@@ -117,17 +117,15 @@ static const mozilla::Module::ContractID
 static void nsWidgetAndroidModuleDtor() {
   // Shutdown all XP level widget classes.
   mozilla::widget::WidgetUtils::Shutdown();
 
   nsLookAndFeel::Shutdown();
   nsAppShellShutdown();
 }
 
-static const mozilla::Module kWidgetModule = {mozilla::Module::kVersion,
+extern const mozilla::Module kWidgetModule = {mozilla::Module::kVersion,
                                               kWidgetCIDs,
                                               kWidgetContracts,
                                               nullptr,
                                               nullptr,
                                               nsAppShellInit,
                                               nsWidgetAndroidModuleDtor};
-
-NSMODULE_DEFN(nsWidgetAndroidModule) = &kWidgetModule;
--- a/widget/cocoa/nsWidgetFactory.mm
+++ b/widget/cocoa/nsWidgetFactory.mm
@@ -195,18 +195,16 @@ static void nsWidgetCocoaModuleDtor() {
   WidgetUtils::Shutdown();
 
   NativeKeyBindings::Shutdown();
   nsLookAndFeel::Shutdown();
   nsToolkit::Shutdown();
   nsAppShellShutdown();
 }
 
-static const mozilla::Module kWidgetModule = {mozilla::Module::kVersion,
+extern const mozilla::Module kWidgetModule = {mozilla::Module::kVersion,
                                               kWidgetCIDs,
                                               kWidgetContracts,
                                               NULL,
                                               NULL,
                                               nsAppShellInit,
                                               nsWidgetCocoaModuleDtor,
                                               mozilla::Module::ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS};
-
-NSMODULE_DEFN(nsWidgetMacModule) = &kWidgetModule;
--- a/widget/nsContentProcessWidgetFactory.cpp
+++ b/widget/nsContentProcessWidgetFactory.cpp
@@ -56,12 +56,10 @@ static const mozilla::Module::ContractID
      Module::CONTENT_PROCESS_ONLY},
     {"@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
      Module::CONTENT_PROCESS_ONLY},
     {"@mozilla.org/sound;1", &kNS_SOUND_CID, Module::CONTENT_PROCESS_ONLY},
     {"@mozilla.org/widget/dragservice;1", &kNS_DRAGSERVICE_CID,
      Module::CONTENT_PROCESS_ONLY},
     {nullptr}};
 
-static const mozilla::Module kWidgetModule = {mozilla::Module::kVersion,
-                                              kWidgetCIDs, kWidgetContracts};
-
-NSMODULE_DEFN(nsContentProcessWidgetModule) = &kWidgetModule;
+extern const mozilla::Module kContentProcessWidgetModule = {
+    mozilla::Module::kVersion, kWidgetCIDs, kWidgetContracts};
--- a/widget/uikit/nsWidgetFactory.mm
+++ b/widget/uikit/nsWidgetFactory.mm
@@ -41,13 +41,11 @@ static const mozilla::Module::ContractID
     {"@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID},
     {nullptr}};
 
 static void nsWidgetUIKitModuleDtor() {
   nsLookAndFeel::Shutdown();
   nsAppShellShutdown();
 }
 
-static const mozilla::Module kWidgetModule = {
+extern const mozilla::Module kWidgetModule = {
     mozilla::Module::kVersion, kWidgetCIDs, kWidgetContracts, nullptr, nullptr, nsAppShellInit,
     nsWidgetUIKitModuleDtor};
-
-NSMODULE_DEFN(nsWidgetUIKitModule) = &kWidgetModule;
--- a/xpcom/build/XPCOMInit.cpp
+++ b/xpcom/build/XPCOMInit.cpp
@@ -170,36 +170,16 @@ const mozilla::Module kXPCOMModule = {
     kXPCOMCIDEntries,
     kXPCOMContracts,
     nullptr,
     nullptr,
     nullptr,
     nullptr,
     Module::ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS};
 
-// FIXME: Dummy modules to avoid Windows PGO bustage when we have too few
-// modules registered.
-static const mozilla::Module kDummy1 = {mozilla::Module::kVersion};
-static const mozilla::Module kDummy2 = {mozilla::Module::kVersion};
-static const mozilla::Module kDummy3 = {mozilla::Module::kVersion};
-static const mozilla::Module kDummy4 = {mozilla::Module::kVersion};
-static const mozilla::Module kDummy5 = {mozilla::Module::kVersion};
-static const mozilla::Module kDummy6 = {mozilla::Module::kVersion};
-static const mozilla::Module kDummy7 = {mozilla::Module::kVersion};
-static const mozilla::Module kDummy8 = {mozilla::Module::kVersion};
-
-NSMODULE_DEFN(Dummy1) = &kDummy1;
-NSMODULE_DEFN(Dummy2) = &kDummy2;
-NSMODULE_DEFN(Dummy3) = &kDummy3;
-NSMODULE_DEFN(Dummy4) = &kDummy4;
-NSMODULE_DEFN(Dummy5) = &kDummy5;
-NSMODULE_DEFN(Dummy6) = &kDummy6;
-NSMODULE_DEFN(Dummy7) = &kDummy7;
-NSMODULE_DEFN(Dummy8) = &kDummy8;
-
 // gDebug will be freed during shutdown.
 static nsIDebug2* gDebug = nullptr;
 
 EXPORT_XPCOM_API(nsresult)
 NS_GetDebug(nsIDebug2** aResult) {
   return nsDebugImpl::Create(nullptr, NS_GET_IID(nsIDebug2), (void**)aResult);
 }
 
--- a/xpcom/components/Module.h
+++ b/xpcom/components/Module.h
@@ -6,17 +6,16 @@
 
 #ifndef mozilla_Module_h
 #define mozilla_Module_h
 
 #include "nscore.h"
 #include "nsID.h"
 #include "nsIFactory.h"
 #include "nsCOMPtr.h"  // for already_AddRefed
-#include "mozilla/Attributes.h"
 
 namespace mozilla {
 
 /**
  * A module implements one or more XPCOM components. This structure is used
  * for both binary and script modules, but the registration members
  * (cids/contractids/categoryentries) are unused for modules which are loaded
  * via a module loader.
@@ -132,44 +131,9 @@ struct Module {
    * Optional flags which control whether the module loads on a process-type
    * basis.
    */
   ProcessSelector selector;
 };
 
 }  // namespace mozilla
 
-#if defined(MOZILLA_INTERNAL_API)
-#  define NSMODULE_NAME(_name) _name##_NSModule
-#  if defined(_MSC_VER) || (defined(__clang__) && defined(__MINGW32__))
-#    pragma section(".kPStaticModules$M", read)
-#    pragma comment(linker, "/merge:.kPStaticModules=.rdata")
-#    define NSMODULE_SECTION \
-      __declspec(allocate(".kPStaticModules$M"), dllexport)
-#  elif defined(__GNUC__)
-#    if defined(__ELF__)
-#      define NSMODULE_SECTION \
-        __attribute__((section("kPStaticModules"), visibility("default")))
-#    elif defined(__MACH__)
-#      define NSMODULE_SECTION \
-        __attribute__(         \
-            (section("__DATA, .kPStaticModules"), visibility("default")))
-#    elif defined(_WIN32)
-#      define NSMODULE_SECTION \
-        __attribute__((section("kPStaticModules"), dllexport))
-#    endif
-#  endif
-#  if !defined(NSMODULE_SECTION)
-#    error Do not know how to define sections.
-#  endif
-#  if defined(MOZ_HAVE_ASAN_BLACKLIST)
-#    define NSMODULE_ASAN_BLACKLIST __attribute__((no_sanitize_address))
-#  else
-#    define NSMODULE_ASAN_BLACKLIST
-#  endif
-#  define NSMODULE_DEFN(_name)                      \
-    extern NSMODULE_SECTION NSMODULE_ASAN_BLACKLIST \
-        mozilla::Module const* const NSMODULE_NAME(_name)
-#else
-#  error Building binary XPCOM components is not supported anymore.
-#endif
-
 #endif  // mozilla_Module_h
--- a/xpcom/components/moz.build
+++ b/xpcom/components/moz.build
@@ -71,9 +71,12 @@ LOCAL_INCLUDES += [
     '/js/xpconnect/loader',
     '/layout/build',
     '/modules/libjar',
 ]
 
 if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
     CXXFLAGS += CONFIG['TK_CFLAGS']
 
+if CONFIG['MOZ_LAYOUT_DEBUGGER']:
+    DEFINES['MOZ_LAYOUT_DEBUGGER'] = True
+
 include('/ipc/chromium/chromium-config.mozbuild')
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -341,97 +341,58 @@ nsresult nsComponentManagerImpl::Create(
 static const int CONTRACTID_HASHTABLE_INITIAL_LENGTH = 32;
 
 nsComponentManagerImpl::nsComponentManagerImpl()
     : mFactories(CONTRACTID_HASHTABLE_INITIAL_LENGTH),
       mContractIDs(CONTRACTID_HASHTABLE_INITIAL_LENGTH),
       mLock("nsComponentManagerImpl.mLock"),
       mStatus(NOT_INITIALIZED) {}
 
-static nsTArray<const mozilla::Module*>* sExtraStaticModules;
-
-/* NSMODULE_DEFN places NSModules in specific sections, as per Module.h.
- * The linker will group them all together, and we use tricks below to
- * find the start and end of the grouped list of NSModules.
- *
- * On Windows, all the symbols in the .kPStaticModules* sections are
- * grouped together, by lexical order of the section names. The NSModules
- * themselves are in .kPStaticModules$M. We use the section name
- * .kPStaticModules$A to add an empty entry that will be the first,
- * and the section name .kPStaticModules$Z for another empty entry that
- * will be the last. We make both null pointers, and skip them in the
- * AllStaticModules range-iterator.
- *
- * On ELF (Linux, BSDs, ...), as well as Mingw builds, the linker itself
- * provides symbols for the beginning and end of the consolidated section,
- * but it only does so for sections that can be represented as C identifiers,
- * so the section is named `kPStaticModules` rather than `.kPStaticModules`.
- *
- * We also use a linker script with BFD ld so that the sections end up
- * folded into the .data.rel.ro section, but that actually breaks the above
- * described behavior, so the linker script contains an additional trick
- * to still provide the __start and __stop symbols (the linker script
- * doesn't work with gold or lld).
- *
- * On Darwin, a similar setup is available through the use of some
- * synthesized symbols (section$...).
- *
- * On all platforms, the __stop_kPStaticModules symbol is past all NSModule
- * pointers.
- * On Windows, the __start_kPStaticModules symbol points to an empty pointer
- * preceding the first NSModule pointer. On other platforms, it points to the
- * first NSModule pointer.
- */
-
-// Dummy class to define a range-iterator for the static modules.
-class AllStaticModules {};
-
-#if defined(_MSC_VER) || (defined(__clang__) && defined(__MINGW32__))
-
-#  pragma section(".kPStaticModules$A", read)
-NSMODULE_ASAN_BLACKLIST __declspec(allocate(".kPStaticModules$A"),
-                                   dllexport) extern mozilla::Module
-    const* const __start_kPStaticModules = nullptr;
-
-mozilla::Module const* const* begin(AllStaticModules& _) {
-  return &__start_kPStaticModules + 1;
+extern const mozilla::Module kNeckoModule;
+extern const mozilla::Module kParserModule;
+#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) || defined(MOZ_WIDGET_ANDROID)
+extern const mozilla::Module kSpeechSynthModule;
+#endif
+extern const mozilla::Module kPowerManagerModule;
+extern const mozilla::Module kContentProcessWidgetModule;
+#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_COCOA) || defined(MOZ_WIDGET_UIKIT)
+extern const mozilla::Module kWidgetModule;
+#endif
+extern const mozilla::Module kLayoutModule;
+namespace mozilla {
+extern const mozilla::Module kLocalCertServiceModule;
 }
-
-#  pragma section(".kPStaticModules$Z", read)
-NSMODULE_ASAN_BLACKLIST __declspec(allocate(".kPStaticModules$Z"),
-                                   dllexport) extern mozilla::Module
-    const* const __stop_kPStaticModules = nullptr;
-
-#else
-
-#  if defined(__ELF__) || (defined(_WIN32) && defined(__GNUC__))
-
-extern "C" mozilla::Module const* const __start_kPStaticModules;
-extern "C" mozilla::Module const* const __stop_kPStaticModules;
-
-#  elif defined(__MACH__)
-
-extern mozilla::Module const* const __start_kPStaticModules __asm(
-    "section$start$__DATA$.kPStaticModules");
-extern mozilla::Module const* const __stop_kPStaticModules __asm(
-    "section$end$__DATA$.kPStaticModules");
-
-#  else
-#    error Do not know how to find NSModules.
-#  endif
-
-static mozilla::Module const* const* begin(AllStaticModules& _) {
-  return &__start_kPStaticModules;
+extern const mozilla::Module kKeyValueModule;
+extern const mozilla::Module kXREModule;
+extern const mozilla::Module kEmbeddingModule;
+#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) || defined(MOZ_WIDGET_ANDROID)
+extern const mozilla::Module kSysProxyModule;
+#endif
+#if defined(XP_WIN)
+namespace mozilla {
+namespace toolkit {
+namespace system {
+namespace windowsDHCPClient {
+extern const mozilla::Module kSysDHCPClientModule;
 }
-
+}  // namespace system
+}  // namespace toolkit
+}  // namespace mozilla
+#endif
+#if defined(MOZ_WIDGET_ANDROID)
+extern const mozilla::Module kBrowserModule;
+#endif
+#if defined(MOZ_LAYOUT_DEBUGGER) && !defined(MOZ_WIDGET_ANDROID)
+extern const mozilla::Module kLayoutDebugModule;
+#endif
+#if defined(MOZ_CODE_COVERAGE)
+extern const mozilla::Module kCodeCoverageModule;
 #endif
 
-static mozilla::Module const* const* end(AllStaticModules& _) {
-  return &__stop_kPStaticModules;
-}
+static nsTArray<const mozilla::Module*>* sExtraStaticModules;
 
 /* static */
 void nsComponentManagerImpl::InitializeStaticModules() {
   if (sExtraStaticModules) {
     return;
   }
 
   sExtraStaticModules = new nsTArray<const mozilla::Module*>;
@@ -481,23 +442,46 @@ nsresult nsComponentManagerImpl::Init() 
   nsCOMPtr<nsIFile> appDir =
       GetLocationFromDirectoryService(NS_XPCOM_CURRENT_PROCESS_DIR);
 
   InitializeStaticModules();
 
   nsCategoryManager::GetSingleton()->SuppressNotifications(true);
 
   RegisterModule(&kXPCOMModule);
-
-  for (auto module : AllStaticModules()) {
-    if (module) {  // On local Windows builds, the list may contain null
-                   // pointers from padding.
-      RegisterModule(module);
-    }
-  }
+  RegisterModule(&kNeckoModule);
+  RegisterModule(&kParserModule);
+#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) || defined(MOZ_WIDGET_ANDROID)
+  RegisterModule(&kSpeechSynthModule);
+#endif
+  RegisterModule(&kPowerManagerModule);
+  RegisterModule(&kContentProcessWidgetModule);
+#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_COCOA) || defined(MOZ_WIDGET_UIKIT)
+  RegisterModule(&kWidgetModule);
+#endif
+  RegisterModule(&kLayoutModule);
+  RegisterModule(&mozilla::kLocalCertServiceModule);
+  RegisterModule(&kKeyValueModule);
+  RegisterModule(&kXREModule);
+  RegisterModule(&kEmbeddingModule);
+#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA) || defined(MOZ_WIDGET_ANDROID)
+  RegisterModule(&kSysProxyModule);
+#endif
+#if defined(XP_WIN)
+  RegisterModule(&mozilla::toolkit::system::windowsDHCPClient::kSysDHCPClientModule);
+#endif
+#if defined(MOZ_WIDGET_ANDROID)
+  RegisterModule(&kBrowserModule);
+#endif
+#if defined(MOZ_LAYOUT_DEBUGGER) && !defined(MOZ_WIDGET_ANDROID)
+  RegisterModule(&kLayoutDebugModule);
+#endif
+#if defined(MOZ_CODE_COVERAGE)
+  RegisterModule(&kCodeCoverageModule);
+#endif
 
   for (uint32_t i = 0; i < sExtraStaticModules->Length(); ++i) {
     RegisterModule((*sExtraStaticModules)[i]);
   }
 
   auto* catMan = nsCategoryManager::GetSingleton();
   for (const auto& cat : gStaticCategories) {
     for (const auto& entry : cat) {