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`.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Aaron Klotz 2019-09-20 00:09:39 +00:00
parent ee19c319fd
commit 64eef06887
5 changed files with 79 additions and 0 deletions

View File

@ -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',

View File

@ -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)

View File

@ -43,8 +43,22 @@ CXXFLAGS += [ SRCDIR + '/Freestanding.h' ]
OS_LIBS += [
'ntdll',
'ntdll_freestanding',
]
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('**'):

View File

@ -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

View File

@ -1209,6 +1209,7 @@ class GeneratedFile(ContextDerived):
suffixes = (
'.h',
'.inc',
context.config.substs['LIB_SUFFIX'],
'.py',
'.rs',
# We need to compile Java to generate JNI wrappers for native code