Bug 938437 - Replace nsStaticXULComponents.cpp with smart use of sections. r=bsmedberg,irc-r=decoder,r=nfroyd,r=gps

This commit is contained in:
Mike Hommey 2013-11-19 13:45:31 +09:00
parent cb8e982360
commit 48917168f9
11 changed files with 101 additions and 316 deletions

View File

@ -240,6 +240,13 @@ if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD"; then
fi
fi
fi
if test "$GNU_CC"; then
if $CC $LDFLAGS -Wl,--version 2>&1 | grep -q "GNU ld"; then
LD_IS_BFD=1
fi
fi
AC_SUBST([LD_IS_BFD])
if test "$GNU_CC"; then
if test -z "$DEVELOPER_OPTIONS"; then

View File

@ -822,6 +822,7 @@ endif
define CHECK_BINARY
$(call CHECK_STDCXX,$(1))
$(call CHECK_TEXTREL,$(1))
$(call LOCAL_CHECKS,$(1))
endef
# autoconf.mk sets OBJ_SUFFIX to an error to avoid use before including

View File

@ -0,0 +1,5 @@
SECTIONS {
.data.rel.ro : {
*(.kPStaticModules)
}
}

View File

@ -0,0 +1,14 @@
#include "mozilla/Module.h"
#include "mozilla/NullPtr.h"
/* Ensure end_kPStaticModules is at the end of the .kPStaticModules section
* on Windows. Somehow, placing the object last is not enough with PGO/LTCG. */
#ifdef _MSC_VER
/* Sections on Windows are in two parts, separated with $. When linking,
* sections with the same first part are all grouped, and ordered
* alphabetically with the second part as sort key. */
# pragma section(".kPStaticModules$Z", read)
# undef NSMODULE_SECTION
# define NSMODULE_SECTION __declspec(allocate(".kPStaticModules$Z"), dllexport)
#endif
NSMODULE_DEFN(end_kPStaticModules) = nullptr;

View File

@ -0,0 +1,11 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
SOURCES += [
'StaticXULComponentsEnd.cpp',
]
LIBRARY_NAME = 'StaticXULComponentsEnd'
DEFINES['MOZILLA_INTERNAL_API'] = True

View File

@ -0,0 +1,4 @@
#include "mozilla/Module.h"
#include "mozilla/NullPtr.h"
NSMODULE_DEFN(start_kPStaticModules) = nullptr;

View File

@ -246,3 +246,28 @@ OS_LIBS += $(LIBICONV)
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
OS_LIBS += $(call EXPAND_LIBNAME,usp10 oleaut32)
endif
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,StaticXULComponentsEnd,$(DEPTH)/toolkit/library/StaticXULComponentsEnd)
# 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.
ifdef LD_IS_BFD
EXTRA_DSO_LDOPTS += $(topsrcdir)/toolkit/library/StaticXULComponents.ld
endif
ifeq (WINNT,$(OS_TARGET))
get_first_and_last = dumpbin -exports $1 | grep _NSModule@@ | sort -k 3 | sed -n 's/^.*?\([^@]*\)@@.*$$/\1/;1p;$$p'
else
get_first_and_last = $(TOOLCHAIN_PREFIX)nm -g $1 | grep _NSModule$$ | sort | sed -n 's/^.* _*\([^ ]*\)$$/\1/;1p;$$p'
endif
LOCAL_CHECKS = test "$$($(get_first_and_last) | xargs echo)" != "start_kPStaticModules_NSModule end_kPStaticModules_NSModule" && echo "NSModules are not ordered appropriately" && exit 1 || exit 0
ifeq (Linux,$(OS_ARCH))
LOCAL_CHECKS += ; test "$$($(TOOLCHAIN_PREFIX)readelf -l $1 | awk '$1 == "LOAD" { t += 1 } END { print t }')" -le 1 && echo "Only one PT_LOAD segment" && exit 1 || exit 0
endif

View File

@ -7,43 +7,18 @@
LIBRARY_NAME = 'xul'
SOURCES += [
'nsStaticXULComponents.cpp',
'StaticXULComponentsStart.cpp',
]
# This, combined with the fact the file is first, makes the start pointer
# it contains first in Windows PGO builds.
SOURCES['StaticXULComponentsStart.cpp'].no_pgo = True
if CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'nsDllMain.cpp',
]
# component libraries
additional_defines = (
'MOZ_AUTH_EXTENSION',
'MOZ_GIO_COMPONENT',
'MOZ_JSDEBUGGER',
'MOZ_PERMISSIONS',
'MOZ_PREF_EXTENSIONS',
'MOZ_SPELLCHECK',
'MOZ_UNIVERSALCHARDET',
'MOZ_ZIPWRITER',
)
for var in additional_defines:
if CONFIG[var]:
DEFINES[var] = True
if CONFIG['MOZ_DEBUG'] and CONFIG['ENABLE_TESTS']:
DEFINES['ENABLE_LAYOUTDEBUG'] = True
if CONFIG['MOZ_WIDGET_TOOLKIT'] not in ('android', 'gonk', 'qt',
'cocoa', 'windows') and \
CONFIG['MOZ_XUL']:
DEFINES['MOZ_FILEVIEW'] = True
# Platform-specific icon channel stuff - supported mostly-everywhere
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'mac', 'cocoa',
'gtk2', 'gtk3', 'qt', 'android'):
DEFINES['ICON_DECODER'] = True
LOCAL_INCLUDES += [
'/config',
# need widget/windows for resource.h (included from widget.rc)
@ -57,4 +32,4 @@ if CONFIG['OS_ARCH'] == 'WINNT' and not CONFIG['GNU_CC']:
FAIL_ON_WARNINGS = True
DIRS += ['build', 'gtest']
DIRS += ['StaticXULComponentsEnd', 'build', 'gtest']

View File

@ -1,276 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Module.h"
#include "nsXPCOM.h"
#include "nsMemory.h"
#ifdef MOZ_AUTH_EXTENSION
#define AUTH_MODULE MODULE(nsAuthModule)
#else
#define AUTH_MODULE
#endif
#ifdef MOZ_PERMISSIONS
#define PERMISSIONS_MODULES \
MODULE(nsCookieModule) \
MODULE(nsPermissionsModule)
#else
#define PERMISSIONS_MODULES
#endif
#ifdef MOZ_UNIVERSALCHARDET
#define UNIVERSALCHARDET_MODULE MODULE(nsUniversalCharDetModule)
#else
#define UNIVERSALCHARDET_MODULE
#endif
#ifdef XP_WIN
# define WIDGET_MODULES MODULE(nsWidgetModule)
#elif defined(XP_MACOSX)
# define WIDGET_MODULES MODULE(nsWidgetMacModule)
#elif defined(MOZ_WIDGET_GTK)
# define WIDGET_MODULES MODULE(nsWidgetGtk2Module)
#elif defined(MOZ_WIDGET_QT)
# define WIDGET_MODULES MODULE(nsWidgetQtModule)
#elif defined(MOZ_WIDGET_ANDROID)
# define WIDGET_MODULES MODULE(nsWidgetAndroidModule)
#elif defined(MOZ_WIDGET_GONK)
# define WIDGET_MODULES MODULE(nsWidgetGonkModule)
#else
# error Unknown widget module.
#endif
#ifndef MOZ_B2G
#define CONTENT_PROCESS_WIDGET_MODULES MODULE(nsContentProcessWidgetModule)
#else
#define CONTENT_PROCESS_WIDGET_MODULES
#endif
#ifdef ICON_DECODER
#define ICON_MODULE MODULE(nsIconDecoderModule)
#else
#define ICON_MODULE
#endif
#ifdef MOZ_ENABLE_XREMOTE
#define XREMOTE_MODULES MODULE(RemoteServiceModule)
#else
#define XREMOTE_MODULES
#endif
#ifdef MOZ_PREF_EXTENSIONS
#define SYSTEMPREF_MODULES MODULE(nsAutoConfigModule)
#else
#define SYSTEMPREF_MODULES
#endif
#ifdef ENABLE_LAYOUTDEBUG
#define LAYOUT_DEBUG_MODULE MODULE(nsLayoutDebugModule)
#else
#define LAYOUT_DEBUG_MODULE
#endif
#ifdef MOZ_JSDEBUGGER
#define JSDEBUGGER_MODULES \
MODULE(JavaScript_Debugger)
#else
#define JSDEBUGGER_MODULES
#endif
#if defined(MOZ_FILEVIEW) && defined(MOZ_XUL)
#define FILEVIEW_MODULE MODULE(nsFileViewModule)
#else
#define FILEVIEW_MODULE
#endif
#ifdef MOZ_ZIPWRITER
#define ZIPWRITER_MODULE MODULE(ZipWriterModule)
#else
#define ZIPWRITER_MODULE
#endif
#ifdef MOZ_PLACES
#define PLACES_MODULES \
MODULE(nsPlacesModule)
#else
#define PLACES_MODULES
#endif
#ifdef MOZ_XUL
#define XULENABLED_MODULES \
MODULE(tkAutoCompleteModule) \
MODULE(satchel) \
MODULE(PKI)
#else
#define XULENABLED_MODULES
#endif
#ifdef MOZ_SPELLCHECK
#define SPELLCHECK_MODULE MODULE(mozSpellCheckerModule)
#else
#define SPELLCHECK_MODULE
#endif
#ifdef MOZ_XUL
#ifdef MOZ_WIDGET_GTK
#define UNIXPROXY_MODULE MODULE(nsUnixProxyModule)
#endif
#if defined(MOZ_WIDGET_QT)
#define UNIXPROXY_MODULE MODULE(nsUnixProxyModule)
#endif
#endif
#ifndef UNIXPROXY_MODULE
#define UNIXPROXY_MODULE
#endif
#if defined(XP_MACOSX)
#define OSXPROXY_MODULE MODULE(nsOSXProxyModule)
#else
#define OSXPROXY_MODULE
#endif
#if defined(XP_WIN)
#define WINDOWSPROXY_MODULE MODULE(nsWindowsProxyModule)
#else
#define WINDOWSPROXY_MODULE
#endif
#if defined(MOZ_WIDGET_ANDROID)
#define ANDROIDPROXY_MODULE MODULE(nsAndroidProxyModule)
#else
#define ANDROIDPROXY_MODULE
#endif
#if defined(BUILD_CTYPES)
#define JSCTYPES_MODULE MODULE(jsctypes)
#else
#define JSCTYPES_MODULE
#endif
#ifndef MOZ_APP_COMPONENT_MODULES
#if defined(MOZ_APP_COMPONENT_INCLUDE)
#include MOZ_APP_COMPONENT_INCLUDE
#define MOZ_APP_COMPONENT_MODULES APP_COMPONENT_MODULES
#else
#define MOZ_APP_COMPONENT_MODULES
#endif
#endif
#if defined(MOZ_ENABLE_PROFILER_SPS)
#define PROFILER_MODULE MODULE(nsProfilerModule)
#else
#define PROFILER_MODULE
#endif
#if defined(MOZ_WEBRTC)
#define PEERCONNECTION_MODULE MODULE(peerconnection)
#else
#define PEERCONNECTION_MODULE
#endif
#if defined(MOZ_GIO_COMPONENT)
#define GIO_MODULE MODULE(nsGIOModule)
#else
#define GIO_MODULE
#endif
#if defined(MOZ_SYNTH_PICO)
#define SYNTH_PICO_MODULE MODULE(synthpico)
#else
#define SYNTH_PICO_MODULE
#endif
#define XUL_MODULES \
MODULE(nsUConvModule) \
MODULE(nsI18nModule) \
MODULE(nsChardetModule) \
UNIVERSALCHARDET_MODULE \
MODULE(necko) \
PERMISSIONS_MODULES \
AUTH_MODULE \
MODULE(nsJarModule) \
ZIPWRITER_MODULE \
MODULE(StartupCacheModule) \
MODULE(nsPrefModule) \
MODULE(nsRDFModule) \
MODULE(nsWindowDataSourceModule) \
MODULE(nsParserModule) \
MODULE(nsImageLib2Module) \
MODULE(nsMediaSnifferModule) \
MODULE(nsGfxModule) \
PROFILER_MODULE \
WIDGET_MODULES \
CONTENT_PROCESS_WIDGET_MODULES \
ICON_MODULE \
MODULE(nsPluginModule) \
MODULE(nsLayoutModule) \
MODULE(docshell_provider) \
MODULE(embedcomponents) \
MODULE(Browser_Embedding_Module) \
MODULE(appshell) \
MODULE(nsTransactionManagerModule) \
MODULE(nsComposerModule) \
MODULE(application) \
MODULE(Apprunner) \
MODULE(CommandLineModule) \
FILEVIEW_MODULE \
MODULE(mozStorageModule) \
PLACES_MODULES \
XULENABLED_MODULES \
MODULE(nsToolkitCompsModule) \
XREMOTE_MODULES \
JSDEBUGGER_MODULES \
MODULE(BOOT) \
MODULE(NSS) \
SYSTEMPREF_MODULES \
SPELLCHECK_MODULE \
LAYOUT_DEBUG_MODULE \
UNIXPROXY_MODULE \
OSXPROXY_MODULE \
WINDOWSPROXY_MODULE \
ANDROIDPROXY_MODULE \
JSCTYPES_MODULE \
MODULE(jsreflect) \
MODULE(jsperf) \
MODULE(identity) \
MODULE(nsServicesCryptoModule) \
MOZ_APP_COMPONENT_MODULES \
MODULE(nsTelemetryModule) \
MODULE(jsinspector) \
MODULE(jsdebugger) \
PEERCONNECTION_MODULE \
GIO_MODULE \
SYNTH_PICO_MODULE \
MODULE(DiskSpaceWatcherModule) \
/* end of list */
#define MODULE(_name) \
NSMODULE_DECL(_name);
XUL_MODULES
#ifdef MOZ_WIDGET_GONK
MODULE(WifiCertServiceModule)
MODULE(WifiProxyServiceModule)
MODULE(NetworkWorkerModule)
#endif
#undef MODULE
#define MODULE(_name) \
&NSMODULE_NAME(_name),
extern const mozilla::Module *const *const kPStaticModules[] = {
XUL_MODULES
#ifdef MOZ_WIDGET_GONK
MODULE(WifiCertServiceModule)
MODULE(WifiProxyServiceModule)
MODULE(NetworkWorkerModule)
#endif
nullptr
};
#undef MODULE

View File

@ -118,8 +118,21 @@ struct Module
#if defined(MOZILLA_INTERNAL_API)
# define NSMODULE_NAME(_name) _name##_NSModule
# define NSMODULE_DECL(_name) extern mozilla::Module const *const NSMODULE_NAME(_name)
# define NSMODULE_DEFN(_name) NSMODULE_DECL(_name)
# if defined(_MSC_VER)
# 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("protected")))
# elif defined(__MACH__)
# define NSMODULE_SECTION __attribute__((section("__DATA, .kPStaticModules"), visibility("default")))
# endif
# endif
# if !defined(NSMODULE_SECTION)
# error Do not know how to define sections.
# endif
# define NSMODULE_DEFN(_name) extern NSMODULE_SECTION mozilla::Module const *const NSMODULE_NAME(_name)
#else
# define NSMODULE_NAME(_name) NSModule
# define NSMODULE_DEFN(_name) extern "C" NS_EXPORT mozilla::Module const *const NSModule

View File

@ -81,10 +81,6 @@ using namespace mozilla;
PRLogModuleInfo* nsComponentManagerLog = nullptr;
// defined in nsStaticXULComponents.cpp to contain all the components in
// libxul.
extern mozilla::Module const *const *const kPStaticModules[];
#if 0 || defined (DEBUG_timeless)
#define SHOW_DENIED_ON_SHUTDOWN
#define SHOW_CI_ON_EXISTING_SERVICE
@ -278,6 +274,15 @@ nsComponentManagerImpl::nsComponentManagerImpl()
nsTArray<const mozilla::Module*>* nsComponentManagerImpl::sStaticModules;
NSMODULE_DEFN(start_kPStaticModules);
NSMODULE_DEFN(end_kPStaticModules);
/* The content between start_kPStaticModules and end_kPStaticModules is gathered
* by the linker from various objects containing symbols in a specific section.
* ASAN considers (rightfully) the use of this content as a global buffer
* overflow. But this is a deliberate and well-considered choice, with no proper
* way to make ASAN happy. */
MOZ_ASAN_BLACKLIST
/* static */ void
nsComponentManagerImpl::InitializeStaticModules()
{
@ -285,9 +290,10 @@ nsComponentManagerImpl::InitializeStaticModules()
return;
sStaticModules = new nsTArray<const mozilla::Module*>;
for (const mozilla::Module *const *const *staticModules = kPStaticModules;
*staticModules; ++staticModules)
sStaticModules->AppendElement(**staticModules);
for (const mozilla::Module *const *staticModules = &NSMODULE_NAME(start_kPStaticModules) + 1;
staticModules < &NSMODULE_NAME(end_kPStaticModules); ++staticModules)
if (*staticModules) // ASAN adds padding
sStaticModules->AppendElement(*staticModules);
}
nsTArray<nsComponentManagerImpl::ComponentLocation>*