Skip to content

Commit

Permalink
Chrome Early Loading Framework
Browse files Browse the repository at this point in the history
chrome_elf.dll is shipped in Chrome's version directory to
ease updates, and is loaded early in chrome.exe's lifetime 
by making it a private assembly in a subfolder of 
chrome.exe's folder (see 
http://msdn.microsoft.com/library/aa374224.aspx).


BUG= http://crosbug.com/p/23889

Review URL: https://codereview.chromium.org/53793002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@234795 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
caitkp@chromium.org committed Nov 13, 2013
1 parent a644bc1 commit 91f0755
Show file tree
Hide file tree
Showing 17 changed files with 201 additions and 0 deletions.
1 change: 1 addition & 0 deletions chrome/app/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ include_rules = [
"+chrome/plugin/chrome_content_plugin_client.h",
"+chrome/renderer/chrome_content_renderer_client.h",
"+chrome/utility/chrome_content_utility_client.h",
"+chrome_elf/chrome_elf_main.h",
"+chromeos/chromeos_paths.h",
"+chromeos/chromeos_switches.h",
"+components/breakpad",
Expand Down
5 changes: 5 additions & 0 deletions chrome/app/chrome_exe_main_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome_elf/chrome_elf_main.h"
#include "components/breakpad/app/breakpad_client.h"
#include "components/breakpad/app/breakpad_win.h"
#include "content/public/app/startup_helper_win.h"
Expand Down Expand Up @@ -119,6 +120,10 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE prev, wchar_t*, int) {
if (AttemptFastNotify(*CommandLine::ForCurrentProcess()))
return 0;

// The purpose of this call is to force the addition of an entry in the IAT
// for chrome_elf.dll to force a load time dependency.
InitChromeElf();

MetroDriver metro_driver;
if (metro_driver.in_metro_mode())
return metro_driver.RunInMetro(instance, &RunChrome);
Expand Down
14 changes: 14 additions & 0 deletions chrome/chrome_exe.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@
'../base/base.gyp:base',
'../breakpad/breakpad.gyp:breakpad_handler',
'../breakpad/breakpad.gyp:breakpad_sender',
'../chrome_elf/chrome_elf.gyp:chrome_elf',
'../components/components.gyp:breakpad_component',
'../sandbox/sandbox.gyp:sandbox',
'app/policy/cloud_policy_codegen.gyp:policy',
Expand Down Expand Up @@ -498,6 +499,7 @@
'VCManifestTool': {
'AdditionalManifestFiles': [
'$(ProjectDir)\\app\\chrome.exe.manifest',
'<(SHARED_INTERMEDIATE_DIR)/chrome_elf/version_assembly.manifest',
],
},
},
Expand All @@ -514,6 +516,18 @@
'message': 'Copy first run complete sentinel file',
'msvs_cygwin_shell': 1,
},
{
'action_name': 'chrome_exe_manifest',
'includes': [
'../chrome_elf/chrome_exe_manifest_action.gypi',
],
},
{
'action_name': 'version_assembly_manifest',
'includes': [
'../chrome_elf/version_assembly_manifest_action.gypi',
],
},
],
}, { # 'OS!="win"
'sources!': [
Expand Down
8 changes: 8 additions & 0 deletions chrome/installer/mini_installer/chrome.release
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@
chrome.exe: %(ChromeDir)s\
wow_helper.exe: %(ChromeDir)s\
#
# Chrome version dir aseembly manifest.
# The name of this file must match the name of the version dir, so we cannot
# hard-code it.
# // TODO(caitkp): Find a way to do this without wildcards.
#
*.*.*.*.manifest: %(VersionDir)s\
#
# Chrome version dir entries, sorted alphabetically.
#
chrome.dll: %(VersionDir)s\
chrome_100_percent.pak: %(VersionDir)s\
chrome_elf.dll: %(VersionDir)s\
chrome_child.dll: %(VersionDir)s\
chrome_frame_helper.dll: %(VersionDir)s\
chrome_frame_helper.exe: %(VersionDir)s\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
"$PROGRAM_FILES\\$CHROME_DIR\\Application\\chrome.exe": {"exists": true},
"$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\chrome.dll":
{"exists": true},
"$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\chrome_elf.dll":
{"exists": true},
"$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\Installer\\chrome.7z":
{"exists": true},
"$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\Installer\\setup.exe":
{"exists": true},
"$PROGRAM_FILES\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\$MINI_INSTALLER_FILE_VERSION.manifest":
{"exists": true}
},
"RegistryEntries": {
Expand Down
4 changes: 4 additions & 0 deletions chrome/test/mini_installer/config/chrome_user_installed.prop
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\chrome.exe": {"exists": true},
"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\chrome.dll":
{"exists": true},
"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\chrome_elf.dll":
{"exists": true},
"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\Installer\\chrome.7z":
{"exists": true},
"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\Installer\\setup.exe":
{"exists": true},
"$LOCAL_APPDATA\\$CHROME_DIR\\Application\\$MINI_INSTALLER_FILE_VERSION\\$MINI_INSTALLER_FILE_VERSION.manifest":
{"exists": true}
},
"RegistryEntries": {
Expand Down
2 changes: 2 additions & 0 deletions chrome_elf/DEPS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include_rules = [
]
3 changes: 3 additions & 0 deletions chrome_elf/OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
caitkp@chromium.org
gab@chromium.org
robertshield@chromium.org
15 changes: 15 additions & 0 deletions chrome_elf/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Chrome Early Loading Framework (aka ChromeELF)

chrome_elf.dll is shipped in Chrome's version directory to ease updates,
and is loaded early in chrome.exe's lifetime. This is done by turning the
version directory into a private assembly which refers to chrome_elf.dll
(http://msdn.microsoft.com/library/aa374224.aspx).

In an ideal world, this would be done by embedding an application config in
chrome.exe that would refer to the proper version directory via a
probing\privatePath attribute (http://msdn.microsoft.com/library/aa374182.aspx).
This would allow us to refer to dlls in the version directory without having to
make the version directory itself into an assembly. It would also avoid naming
conflicts (as the WinSxS dir and GAC both take precedence over private
assemblies when searching for dlls). Unfortunately, the probing\privatePath
attribute is only supported for Windows 7 and later.
4 changes: 4 additions & 0 deletions chrome_elf/chrome_elf.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
LIBRARY "chrome_elf.dll"

EXPORTS
InitChromeElf
26 changes: 26 additions & 0 deletions chrome_elf/chrome_elf.gyp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'variables': {
'chromium_code': 1,
},
'includes': [
'../build/win_precompile.gypi',
'../chrome/version.gypi',
],
'targets': [
{
'target_name': 'chrome_elf',
'type': 'shared_library',
'include_dirs': [
'..',
],
'sources': [
'chrome_elf.def',
'chrome_elf_main.cc',
'chrome_elf_main.h',
],
},
],
}
16 changes: 16 additions & 0 deletions chrome_elf/chrome_elf_main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <windows.h>

#include "chrome_elf/chrome_elf_main.h"

void InitChromeElf() {
// This method is a no-op which may be called to force a load-time dependency
// on chrome_elf.dll.
}

BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) {
return TRUE;
}
10 changes: 10 additions & 0 deletions chrome_elf/chrome_elf_main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_ELF_CHROME_ELF_MAIN_H_
#define CHROME_ELF_CHROME_ELF_MAIN_H_

extern "C" void InitChromeElf();

#endif // CHROME_ELF_CHROME_ELF_MAIN_H_
10 changes: 10 additions & 0 deletions chrome_elf/chrome_exe_manifest.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32'
name='@MAJOR@.@MINOR@.@BUILD@.@PATCH@'
version='@MAJOR@.@MINOR@.@BUILD@.@PATCH@' language='*'/>
</dependentAssembly>
</dependency>
</assembly>
34 changes: 34 additions & 0 deletions chrome_elf/chrome_exe_manifest_action.gypi
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This file contains an action which can be used to construct a manifest file
# declaring a dependency on chrome_elf.dll. This manifest can then be merged
# into the manifest of the executable and embedded into it when it is built.

# To use this the following variables need to be defined:
# version_path: string: path to file containing version data (e.g.
# chrome/VERSION).
# version_py_path: string: path to file containing version script (e.g.
# chrome/tools/build/version.py).

{
'variables': {
'template_input_path':
'<(DEPTH)/chrome_elf/chrome_exe_manifest.template',
},
'inputs': [
'<(template_input_path)',
'<(version_path)',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/chrome_elf/version_assembly.manifest',
],
'action': [
'python', '<(version_py_path)',
'-f', '<(version_path)',
'<(template_input_path)',
'<@(_outputs)',
],
'message': 'Generating <@(_outputs)',
}
8 changes: 8 additions & 0 deletions chrome_elf/version_assembly_manifest.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<assembly
xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<assemblyIdentity
name='@MAJOR@.@MINOR@.@BUILD@.@PATCH@'
version='@MAJOR@.@MINOR@.@BUILD@.@PATCH@'
type='win32'/>
<file name='chrome_elf.dll'/>
</assembly>
37 changes: 37 additions & 0 deletions chrome_elf/version_assembly_manifest_action.gypi
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This file contains an action which can be used to construct a manifest file
# with the same name as the version directory so that chrome.exe identifies the
# version directory as an assembly. This will be copied over to the version
# directory by the installer script.

# To use this the following variables need to be defined:
# version_path: string: path to file containing version data (e.g.
# chrome/VERSION).
# version_py_path: string: path to file containing version script (e.g.
# chrome/tools/build/version.py).
# version_full: string: version string in W.X.Y.Z form.


{
'variables': {
'template_input_path':
'<(DEPTH)/chrome_elf/version_assembly_manifest.template',
},
'inputs': [
'<(template_input_path)',
'<(version_path)',
],
'outputs': [
'<(PRODUCT_DIR)/<(version_full).manifest',
],
'action': [
'python', '<(version_py_path)',
'-f', '<(version_path)',
'<(template_input_path)',
'<@(_outputs)',
],
'message': 'Generating <@(_outputs)',
}

0 comments on commit 91f0755

Please sign in to comment.