Bug 1542830: Part 3 - Add ntdll_freestanding.lib to freestanding; r=mhowell,froydnj

The `freestanding` library is built with specific compiler flags to signify
that it is indeed freestanding code. That is, it does not depend on a
standard library.

One of the requirements of freestanding code is that the toolchain still
expects implementations of `memcpy`, `memmove`, `memcmp`, and `memset`.

I did briefly implement my own naive versions of these functions, but that
solution is less than ideal since the implementations must be `extern` and are
thus picked up by the entire `firefox.exe` binary. This denies the rest of
`firefox.exe` the benefit of optimized implementations. On Windows, the
sandbox is linked into `firefox.exe`, so we cannot just shrug and
assume that naive implementations will not have any effect on anything.

There are, however, optimized implementations of these functions that are
exported by `ntdll.dll`. They are not included in the `ntdll.lib` that is
included in the Windows SDK. Using `llvm-dlltool`, we can build an import
library containing the missing entries and then add that library to `OS_LIBS`.

Depends on D43156

Differential Revision: https://phabricator.services.mozilla.com/D43157

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Aaron Klotz 2019-09-23 20:18:37 +00:00
Родитель 5690759b5c
Коммит f9be0e1c7f
5 изменённых файлов: 91 добавлений и 2 удалений

Просмотреть файл

@ -86,6 +86,15 @@ if CONFIG['OS_ARCH'] == 'WINNT':
'version.dll',
]
if CONFIG['CC_TYPE'] == 'clang-cl':
libpath_flag = '-LIBPATH:'
else:
libpath_flag = '-L'
WIN32_EXE_LDFLAGS += [
libpath_flag + OBJDIR + '/winlauncher/freestanding',
]
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'Darwin':
USE_LIBS += [
'mozsandbox',

Просмотреть файл

@ -0,0 +1,30 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
from __future__ import absolute_import
import os
import subprocess
import tempfile
def main(output_fd, def_file, llvm_dlltool, *llvm_dlltool_args):
# llvm-dlltool can't output to stdout, so we create a temp file, use that
# to write out the lib, and then copy it over to output_fd
(tmp_fd, tmp_output) = tempfile.mkstemp()
os.close(tmp_fd)
try:
cmd = [llvm_dlltool]
cmd.extend(llvm_dlltool_args)
cmd += ['-d', def_file, '-l', tmp_output]
subprocess.check_call(cmd)
with open(tmp_output, 'rb') as tmplib:
output_fd.write(tmplib.read())
finally:
os.remove(tmp_output)

Просмотреть файл

@ -43,8 +43,23 @@ CXXFLAGS += [ SRCDIR + '/Freestanding.h' ]
OS_LIBS += [
'ntdll',
'ntdll_freestanding',
]
if CONFIG['COMPILE_ENVIRONMENT']:
ntdll_freestanding_lib = '%sntdll_freestanding.%s' % (CONFIG['LIB_PREFIX'],
CONFIG['LIB_SUFFIX'])
GENERATED_FILES += [
ntdll_freestanding_lib,
]
ntdll_freestanding_gen = GENERATED_FILES[ntdll_freestanding_lib]
ntdll_freestanding_gen.script = 'gen_ntdll_freestanding_lib.py'
ntdll_freestanding_gen.inputs = ['ntdll_freestanding.def']
ntdll_freestanding_gen.flags = [CONFIG['LLVM_DLLTOOL']] + \
CONFIG['LLVM_DLLTOOL_FLAGS']
DisableStlWrapping()
with Files('**'):

Просмотреть файл

@ -0,0 +1,25 @@
; 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/.
LIBRARY ntdll
; When we compile with -freestanding, the compiler still requires implementation
; of the four functions listed below.
;
; We could implement our own naive versions of these functions, but that
; solution is less than ideal since the implementations must be extern and are
; thus picked up by the entire firefox.exe binary. This denies the rest of
; firefox.exe the benefit of optimized implementations. On Windows the
; sandbox is linked into firefox.exe, so we cannot just shrug and
; assume that a naive implementation will not have any effect on anything.
;
; There are, however, optimized implementations of these functions that are
; exported by ntdll.dll. OTOH, they are not included in the ntdll.lib
; import library. This .def file is used to build an import library that "fills
; in the blanks" and allows us to link into the ntdll implementations.
EXPORTS
memcmp
memcpy
memmove
memset

Просмотреть файл

@ -1206,7 +1206,7 @@ class GeneratedFile(ContextDerived):
self.localized = localized
self.force = force
suffixes = (
suffixes = [
'.h',
'.inc',
'.py',
@ -1216,7 +1216,17 @@ class GeneratedFile(ContextDerived):
'android_apks',
'.profdata',
'.webidl'
)
]
try:
lib_suffix = context.config.substs['LIB_SUFFIX']
suffixes.append('.' + lib_suffix)
except KeyError:
# Tests may not define LIB_SUFFIX
pass
suffixes = tuple(suffixes)
self.required_before_compile = [
f for f in self.outputs if f.endswith(suffixes) or 'stl_wrappers/' in f]