summaryrefslogtreecommitdiff
path: root/build/win32
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /build/win32
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloaduxp-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'build/win32')
-rw-r--r--build/win32/Makefile.in14
-rw-r--r--build/win32/__init__.py0
-rw-r--r--build/win32/autobinscope.py75
-rw-r--r--build/win32/crashinject.cpp96
-rw-r--r--build/win32/crashinjectdll/crashinjectdll.cpp38
-rw-r--r--build/win32/crashinjectdll/crashinjectdll.def7
-rw-r--r--build/win32/crashinjectdll/moz.build15
-rw-r--r--build/win32/dumpenv4python.pl19
-rw-r--r--build/win32/moz.build28
-rw-r--r--build/win32/mozconfig.vs-latest1
-rw-r--r--build/win32/mozconfig.vs2015-win6425
-rwxr-xr-xbuild/win32/pgomerge.py44
-rw-r--r--build/win32/procmem.py48
13 files changed, 410 insertions, 0 deletions
diff --git a/build/win32/Makefile.in b/build/win32/Makefile.in
new file mode 100644
index 0000000000..c96099d8f0
--- /dev/null
+++ b/build/win32/Makefile.in
@@ -0,0 +1,14 @@
+# 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 $(topsrcdir)/config/rules.mk
+
+# run the binscope tool to make sure the binary and all libraries
+# are using all available Windows OS-level security mechanisms
+# Don't do this in clang-cl since it doesn't support debug information yet.
+ifndef CLANG_CL
+check::
+ $(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/$(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/crashreporter-symbols/
+ $(PYTHON) $(srcdir)/autobinscope.py $(DIST)/bin/plugin-container.exe $(DIST)/crashreporter-symbols/
+endif
diff --git a/build/win32/__init__.py b/build/win32/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/build/win32/__init__.py
diff --git a/build/win32/autobinscope.py b/build/win32/autobinscope.py
new file mode 100644
index 0000000000..fdba68e0c3
--- /dev/null
+++ b/build/win32/autobinscope.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env 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/.
+
+# run Microsoft's Binscope tool (http://www.microsoft.com/download/en/details.aspx?id=11910)
+# against a fresh Windows build. output a 'binscope.log' file with full details
+# of the run and appropriate strings to integrate with the buildbots
+
+# from the docs : "The error code returned when running under the command line is equal
+# to the number of failures the tool reported plus the number of errors. BinScope will return
+# 0 only if there are no errors or failures."
+
+# the symbol dir should point to the symbol dir hierarchy created
+# via running make buildsymbols in a windows build's objdir
+
+import sys
+import subprocess
+import os
+
+BINSCOPE_OUTPUT_LOGFILE = r".\binscope_xml_output.log"
+
+# usage
+if len(sys.argv) < 3:
+ print """usage : autobinscope.by path_to_binary path_to_symbols [log_file_path]"
+ log_file_path is optional, log will be written to .\binscope_xml_output.log by default"""
+ sys.exit(0)
+
+binary_path = sys.argv[1]
+symbol_path = sys.argv[2]
+
+if len(sys.argv) == 4:
+ log_file_path = sys.argv[3]
+else:
+ log_file_path = BINSCOPE_OUTPUT_LOGFILE
+
+# execute binscope against the binary, using the BINSCOPE environment
+# variable as the path to binscope.exe
+try:
+ binscope_path = os.environ['BINSCOPE']
+except KeyError:
+ print "BINSCOPE environment variable is not set, can't check DEP/ASLR etc. status."
+ sys.exit(0)
+
+try:
+ proc = subprocess.Popen([binscope_path, "/target", binary_path,
+ "/output", log_file_path, "/sympath", symbol_path,
+ "/c", "ATLVersionCheck", "/c", "ATLVulnCheck", "/c", "SharedSectionCheck", "/c", "APTCACheck", "/c", "NXCheck",
+ "/c", "GSCheck", "/c", "GSFriendlyInitCheck",
+ "/c", "CompilerVersionCheck", "/c", "SafeSEHCheck", "/c", "SNCheck",
+ "/c", "DBCheck"], stdout=subprocess.PIPE)
+
+except WindowsError, (errno, strerror):
+ if errno != 2 and errno != 3:
+ print "Unexpected error ! \nError " + str(errno) + " : " + strerror + "\nExiting !\n"
+ sys.exit(0)
+ else:
+ print "Could not locate binscope at location : %s\n" % binscope_path
+ print "Binscope wasn't installed or the BINSCOPE env variable wasn't set correctly, skipping this check and exiting..."
+ sys.exit(0)
+
+proc.wait()
+
+output = proc.communicate()[0]
+
+# is this a PASS or a FAIL ?
+if proc.returncode != 0:
+ print "Error count: %d" % proc.returncode
+ print "TEST-UNEXPECTED-FAIL | autobinscope.py | %s is missing a needed Windows protection, such as /GS or ASLR" % binary_path
+ logfile = open(log_file_path, "r")
+ for line in logfile:
+ print(line),
+else:
+ print "TEST-PASS | autobinscope.py | %s succeeded" % binary_path
diff --git a/build/win32/crashinject.cpp b/build/win32/crashinject.cpp
new file mode 100644
index 0000000000..472e15a128
--- /dev/null
+++ b/build/win32/crashinject.cpp
@@ -0,0 +1,96 @@
+/* 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/. */
+
+/*
+ * Given a PID, this program attempts to inject a DLL into the process
+ * with that PID. The DLL it attempts to inject, "crashinjectdll.dll",
+ * must exist alongside this exe. The DLL will then crash the process.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+
+int main(int argc, char** argv)
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage: crashinject <PID>\n");
+ return 1;
+ }
+
+ int pid = atoi(argv[1]);
+ if (pid <= 0) {
+ fprintf(stderr, "Usage: crashinject <PID>\n");
+ return 1;
+ }
+
+ // find our DLL to inject
+ wchar_t filename[_MAX_PATH];
+ if (GetModuleFileNameW(nullptr, filename,
+ sizeof(filename) / sizeof(wchar_t)) == 0)
+ return 1;
+
+ wchar_t* slash = wcsrchr(filename, L'\\');
+ if (slash == nullptr)
+ return 1;
+
+ slash++;
+ wcscpy(slash, L"crashinjectdll.dll");
+
+ // now find our target process
+ HANDLE targetProc = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION,
+ FALSE,
+ pid);
+ if (targetProc == nullptr) {
+ fprintf(stderr, "Error %d opening target process\n", GetLastError());
+ return 1;
+ }
+
+ /*
+ * This is sort of insane, but we're implementing a technique described here:
+ * http://www.codeproject.com/KB/threads/winspy.aspx#section_2
+ *
+ * The gist is to use CreateRemoteThread to create a thread in the other
+ * process, but cheat and make the thread function kernel32!LoadLibrary,
+ * so that the only remote data we have to pass to the other process
+ * is the path to the library we want to load. The library we're loading
+ * will then do its dirty work inside the other process.
+ */
+ HMODULE hKernel32 = GetModuleHandleW(L"Kernel32");
+ // allocate some memory to hold the path in the remote process
+ void* pLibRemote = VirtualAllocEx(targetProc, nullptr, sizeof(filename),
+ MEM_COMMIT, PAGE_READWRITE);
+ if (pLibRemote == nullptr) {
+ fprintf(stderr, "Error %d in VirtualAllocEx\n", GetLastError());
+ CloseHandle(targetProc);
+ return 1;
+ }
+
+ if (!WriteProcessMemory(targetProc, pLibRemote, (void*)filename,
+ sizeof(filename), nullptr)) {
+ fprintf(stderr, "Error %d in WriteProcessMemory\n", GetLastError());
+ VirtualFreeEx(targetProc, pLibRemote, sizeof(filename), MEM_RELEASE);
+ CloseHandle(targetProc);
+ return 1;
+ }
+ // Now create a thread in the target process that will load our DLL
+ HANDLE hThread = CreateRemoteThread(
+ targetProc, nullptr, 0,
+ (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32,
+ "LoadLibraryW"),
+ pLibRemote, 0, nullptr);
+ if (hThread == nullptr) {
+ fprintf(stderr, "Error %d in CreateRemoteThread\n", GetLastError());
+ VirtualFreeEx(targetProc, pLibRemote, sizeof(filename), MEM_RELEASE);
+ CloseHandle(targetProc);
+ return 1;
+ }
+ WaitForSingleObject(hThread, INFINITE);
+ // Cleanup, not that it's going to matter at this point
+ CloseHandle(hThread);
+ VirtualFreeEx(targetProc, pLibRemote, sizeof(filename), MEM_RELEASE);
+ CloseHandle(targetProc);
+
+ return 0;
+}
diff --git a/build/win32/crashinjectdll/crashinjectdll.cpp b/build/win32/crashinjectdll/crashinjectdll.cpp
new file mode 100644
index 0000000000..09ab9fdbab
--- /dev/null
+++ b/build/win32/crashinjectdll/crashinjectdll.cpp
@@ -0,0 +1,38 @@
+/* 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 <stdio.h>
+#include <windows.h>
+
+// make sure we only ever spawn one thread
+DWORD tid = -1;
+
+DWORD WINAPI CrashingThread(
+ LPVOID lpParameter
+)
+{
+ // not a very friendly DLL
+ volatile int* x = (int *)0x0;
+ *x = 1;
+ return 0;
+}
+
+BOOL WINAPI DllMain(
+ HANDLE hinstDLL,
+ DWORD dwReason,
+ LPVOID lpvReserved
+)
+{
+ if (tid == -1)
+ // we have to crash on another thread because LoadLibrary() will
+ // catch memory access errors and return failure to the calling process
+ CreateThread(
+ nullptr, // default security attributes
+ 0, // use default stack size
+ CrashingThread, // thread function name
+ nullptr, // argument to thread function
+ 0, // use default creation flags
+ &tid); // returns the thread identifier
+ return TRUE;
+}
diff --git a/build/win32/crashinjectdll/crashinjectdll.def b/build/win32/crashinjectdll/crashinjectdll.def
new file mode 100644
index 0000000000..d1ea5602da
--- /dev/null
+++ b/build/win32/crashinjectdll/crashinjectdll.def
@@ -0,0 +1,7 @@
+;+# 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 crashinjectdll
+EXPORTS
+ DllMain
diff --git a/build/win32/crashinjectdll/moz.build b/build/win32/crashinjectdll/moz.build
new file mode 100644
index 0000000000..06817aa964
--- /dev/null
+++ b/build/win32/crashinjectdll/moz.build
@@ -0,0 +1,15 @@
+# -*- 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/.
+
+SOURCES += [
+ 'crashinjectdll.cpp',
+]
+
+SharedLibrary('crashinjectdll')
+
+DEFFILE = SRCDIR + '/crashinjectdll.def'
+
+USE_STATIC_LIBS = True
diff --git a/build/win32/dumpenv4python.pl b/build/win32/dumpenv4python.pl
new file mode 100644
index 0000000000..34a1135a18
--- /dev/null
+++ b/build/win32/dumpenv4python.pl
@@ -0,0 +1,19 @@
+# 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/.
+
+# See build/autoconf/hooks.m4
+
+use Data::Dumper;
+
+$Data::Dumper::Terse = 1;
+$Data::Dumper::Indent = 0;
+
+# We can't use perl hashes because Mozilla-Build's perl is 5.6, and perl
+# 5.6's Data::Dumper doesn't have Pair to change ' => ' into ' : '.
+@data = (
+ ['env', [map { [$_, $ENV{$_}] } keys %ENV]],
+ ['args', \@ARGV],
+);
+
+print Dumper \@data;
diff --git a/build/win32/moz.build b/build/win32/moz.build
new file mode 100644
index 0000000000..cd5110ac69
--- /dev/null
+++ b/build/win32/moz.build
@@ -0,0 +1,28 @@
+# -*- 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/.
+
+TEST_DIRS += ['crashinjectdll']
+
+if CONFIG['ENABLE_TESTS']:
+ Program('crashinject')
+ SOURCES += [
+ 'crashinject.cpp',
+ ]
+ USE_STATIC_LIBS = True
+
+NO_PGO = True
+
+if CONFIG['WIN32_REDIST_DIR'] and CONFIG['COMPILE_ENVIRONMENT']:
+ for f in ['MSVC_C_RUNTIME_DLL', 'MSVC_CXX_RUNTIME_DLL']:
+ FINAL_TARGET_FILES += [
+ '%%%s/%s' % (CONFIG['WIN32_REDIST_DIR'], CONFIG[f])
+ ]
+
+if CONFIG['WIN_UCRT_REDIST_DIR'] and CONFIG['COMPILE_ENVIRONMENT']:
+ for f in ['api-ms-win-*.dll', 'ucrtbase.dll']:
+ FINAL_TARGET_FILES += [
+ '%%%s/%s' % (CONFIG['WIN_UCRT_REDIST_DIR'], f)
+ ]
diff --git a/build/win32/mozconfig.vs-latest b/build/win32/mozconfig.vs-latest
new file mode 100644
index 0000000000..9c8726a8df
--- /dev/null
+++ b/build/win32/mozconfig.vs-latest
@@ -0,0 +1 @@
+. $topsrcdir/build/win32/mozconfig.vs2015-win64
diff --git a/build/win32/mozconfig.vs2015-win64 b/build/win32/mozconfig.vs2015-win64
new file mode 100644
index 0000000000..b81afa681d
--- /dev/null
+++ b/build/win32/mozconfig.vs2015-win64
@@ -0,0 +1,25 @@
+if [ -z "${VSPATH}" ]; then
+ TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
+ VSPATH="$(cd ${TOOLTOOL_DIR} && pwd)/vs2015u3"
+fi
+
+VSWINPATH="$(cd ${VSPATH} && pwd -W)"
+
+export WINDOWSSDKDIR="${VSWINPATH}/SDK"
+export WIN32_REDIST_DIR="${VSPATH}/VC/redist/x86/Microsoft.VC140.CRT"
+export WIN_UCRT_REDIST_DIR="${VSPATH}/SDK/Redist/ucrt/DLLs/x86"
+
+export PATH="${VSPATH}/VC/bin/amd64_x86:${VSPATH}/VC/bin/amd64:${VSPATH}/VC/bin:${VSPATH}/SDK/bin/x86:${VSPATH}/SDK/bin/x64:${VSPATH}/DIA SDK/bin:${PATH}"
+export PATH="${VSPATH}/VC/redist/x86/Microsoft.VC140.CRT:${VSPATH}/VC/redist/x64/Microsoft.VC140.CRT:${VSPATH}/SDK/Redist/ucrt/DLLs/x86:${VSPATH}/SDK/Redist/ucrt/DLLs/x64:${PATH}"
+
+export INCLUDE="${VSPATH}/VC/include:${VSPATH}/VC/atlmfc/include:${VSPATH}/SDK/Include/10.0.14393.0/ucrt:${VSPATH}/SDK/Include/10.0.14393.0/shared:${VSPATH}/SDK/Include/10.0.14393.0/um:${VSPATH}/SDK/Include/10.0.14393.0/winrt:${VSPATH}/DIA SDK/include"
+export LIB="${VSPATH}/VC/lib:${VSPATH}/VC/atlmfc/lib:${VSPATH}/SDK/lib/10.0.14393.0/ucrt/x86:${VSPATH}/SDK/lib/10.0.14393.0/um/x86:${VSPATH}/DIA SDK/lib"
+
+. $topsrcdir/build/mozconfig.vs-common
+
+mk_export_correct_style WINDOWSSDKDIR
+mk_export_correct_style INCLUDE
+mk_export_correct_style LIB
+mk_export_correct_style PATH
+mk_export_correct_style WIN32_REDIST_DIR
+mk_export_correct_style WIN_UCRT_REDIST_DIR
diff --git a/build/win32/pgomerge.py b/build/win32/pgomerge.py
new file mode 100755
index 0000000000..313d66870d
--- /dev/null
+++ b/build/win32/pgomerge.py
@@ -0,0 +1,44 @@
+#!/usr/bin/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/.
+
+# Usage: pgomerge.py <binary basename> <dist/bin>
+# Gathers .pgc files from dist/bin and merges them into
+# $PWD/$basename.pgd using pgomgr, then deletes them.
+# No errors if any of these files don't exist.
+
+import sys, os, os.path, subprocess
+if not sys.platform == "win32":
+ raise Exception("This script was only meant for Windows.")
+
+def MergePGOFiles(basename, pgddir, pgcdir):
+ """Merge pgc files produced from an instrumented binary
+ into the pgd file for the second pass of profile-guided optimization
+ with MSVC. |basename| is the name of the DLL or EXE without the
+ extension. |pgddir| is the path that contains <basename>.pgd
+ (should be the objdir it was built in). |pgcdir| is the path
+ containing basename!N.pgc files, which is probably dist/bin.
+ Calls pgomgr to merge each pgc file into the pgd, then deletes
+ the pgc files."""
+ if not os.path.isdir(pgddir) or not os.path.isdir(pgcdir):
+ return
+ pgdfile = os.path.abspath(os.path.join(pgddir, basename + ".pgd"))
+ if not os.path.isfile(pgdfile):
+ return
+ for file in os.listdir(pgcdir):
+ if file.startswith(basename+"!") and file.endswith(".pgc"):
+ try:
+ pgcfile = os.path.normpath(os.path.join(pgcdir, file))
+ subprocess.call(['pgomgr', '-merge',
+ pgcfile,
+ pgdfile])
+ os.remove(pgcfile)
+ except OSError:
+ pass
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ print >>sys.stderr, "Usage: pgomerge.py <binary basename> <dist/bin>"
+ sys.exit(1)
+ MergePGOFiles(sys.argv[1], os.getcwd(), sys.argv[2])
diff --git a/build/win32/procmem.py b/build/win32/procmem.py
new file mode 100644
index 0000000000..8376d07ea4
--- /dev/null
+++ b/build/win32/procmem.py
@@ -0,0 +1,48 @@
+# 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/.
+
+import os, sys, ctypes, ctypes.wintypes
+
+class VM_COUNTERS(ctypes.Structure):
+ _fields_ = [("PeakVirtualSize", ctypes.wintypes.ULONG),
+ ("VirtualSize", ctypes.wintypes.ULONG),
+ ("PageFaultCount", ctypes.wintypes.ULONG),
+ ("PeakWorkingSetSize", ctypes.wintypes.ULONG),
+ ("WorkingSetSize", ctypes.wintypes.ULONG),
+ ("QuotaPeakPagedPoolUsage", ctypes.wintypes.ULONG),
+ ("QuotaPagedPoolUsage", ctypes.wintypes.ULONG),
+ ("QuotaPeakNonPagedPoolUsage", ctypes.wintypes.ULONG),
+ ("QuotaNonPagedPoolUsage", ctypes.wintypes.ULONG),
+ ("PagefileUsage", ctypes.wintypes.ULONG),
+ ("PeakPagefileUsage", ctypes.wintypes.ULONG)
+ ]
+
+def get_vmsize(handle):
+ """
+ Return (peak_virtual_size, virtual_size) for the process |handle|.
+ """
+ ProcessVmCounters = 3
+ vmc = VM_COUNTERS()
+ if ctypes.windll.ntdll.NtQueryInformationProcess(int(handle),
+ ProcessVmCounters,
+ ctypes.byref(vmc),
+ ctypes.sizeof(vmc),
+ None) == 0:
+ return (vmc.PeakVirtualSize, vmc.VirtualSize)
+
+ return (-1, -1)
+
+if __name__ == '__main__':
+ PROCESS_QUERY_INFORMATION = 0x0400
+ for pid in sys.argv[1:]:
+ handle = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION,
+ 0, # no inherit
+ int(pid))
+ if handle:
+ print "Process %s:" % pid
+ vsize, peak_vsize = get_vmsize(handle)
+ print "peak vsize: %d" % peak_vsize
+ ctypes.windll.kernel32.CloseHandle(handle)
+ else:
+ print "Couldn't open process %s" % pid