diff --git a/.gitignore b/.gitignore index 2427f32..1e45084 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ testserver.log /toolchain_build/src/ # Ignore these absolute directories (relative to native_client directory) +/build-*/ /build/Debug/ /build/Release/ /chromebinaries/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3bd9468 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,179 @@ +cmake_minimum_required(VERSION 3.12) + +project(native_client C CXX ASM) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}") + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +include(DaemonPlatform/Platform) +include(NaClFlags) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE RelWithDebInfo) +endif() + +option(BUILD_NACL_LOADER "Build the sel_ldr program." ON) + +if (LINUX) + option(BUILD_NACL_HELPER_BOOTSTRAP "Build the nacl_helper_bootstrap program on platforms requiring it." ON) +endif() + +# TODO(arbenson): remove this once binutils bug is fixed (see +# src/trusted/service_runtime/arch/x86_64/sel_addrspace_posix_x86_64.c) +if (BUILD_NACL_LOADER AND ARCH_amd64 AND NOT WIN32) + option(USE_AMD64_ZERO_BASED_SANDBOX "Allow the zero-based sandbox model to run insecurely." OFF) + list(APPEND INHERITED_OPTIONS "USE_AMD64_ZERO_BASED_SANDBOX") +endif() + +if (BUILD_NACL_LOADER AND WIN32) + option(FORCE_NO_TRUSTED_BUILD "Prevent use of trusted toolchain." OFF) +endif() + +if (BUILD_NACL_LOADER AND WIN32) + set(REQUIRE_MASM ON) +endif() + +if (BUILD_NACL_LOADER AND APPLE) + set(REQUIRE_PYTHON ON) +endif() + +if (BUILD_NACL_HELPER_BOOTSTRAP) + set(REQUIRE_PYTHON ON) +endif() + +if (REQUIRE_PYTHON) + if (NOT PYTHON) + find_program(PYTHON NAMES "python3" DOC "Path to the python3 executable." REQUIRED) + endif() +endif() + +if (REQUIRE_MASM) + if (NOT MSVC AND NOT CMAKE_ASM_MASM_COMPILER) + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include-hax/fake_masm") + + find_program(JWASM NAMES "jwasm" DOC "Path to the JWasm executable." REQUIRED) + + set(CMAKE_ASM_MASM_COMPILER "${JWASM}") + + if (ARCH_i686) + list(APPEND CMAKE_ASM_MASM_FLAGS "-coff") + elseif(ARCH_amd64) + list(APPEND CMAKE_ASM_MASM_FLAGS "-win64") + endif() + endif() + + enable_language(ASM_MASM) +endif() + +include_directories("include-hax") + +if (ARCH_i686) + set(ARCH_SUFFIX "_x86_32") +elseif (ARCH_amd64) + set(ARCH_SUFFIX "_X86_64") +elseif (ARCH_armhf OR ARCH_armel) + set(ARCH_SUFFIX "_arm") +elseif (ARCH_mipsel) + set(ARCH_SUFFIX "_mips32") +endif() + +if (BUILD_NACL_LOADER) + add_subdirectory(src/shared/gio) + add_subdirectory(src/shared/imc) + add_subdirectory(src/shared/platform) + add_subdirectory(src/trusted/cpu_features) + add_subdirectory(src/trusted/debug_stub) + add_subdirectory(src/trusted/desc) + add_subdirectory(src/trusted/fault_injection) + add_subdirectory(src/trusted/interval_multiset) + add_subdirectory(src/trusted/nacl_base) + add_subdirectory(src/trusted/perf_counter) + add_subdirectory(src/trusted/platform_qualify) + add_subdirectory(src/trusted/validator) + + if (ARCH_i686 OR ARCH_amd64) + add_subdirectory(src/trusted/validator_x86) + add_subdirectory(src/trusted/validator_ragel) + elseif (ARCH_armhf OR ARCH_armel) + add_subdirectory(src/trusted/validator_arm) + elseif (ARCH_mipsel) + add_subdirectory(src/trusted/validator_mips) + endif() +endif() + +if (BUILD_NACL_LOADER) + add_subdirectory(src/trusted/service_runtime) +endif() + +if (BUILD_NACL_HELPER_BOOTSTRAP) + option(BUILD_NACL_HELPER_BOOTSTRAP_WITH_CLANG "Build the nacl_helper_bootstrap program with Clang." ON) +endif() + +if (BUILD_NACL_HELPER_BOOTSTRAP) + if (DAEMON_C_COMPILER_Clang_COMPATIBILITY) + set(BUILD_BOOTSTRAP_DIRECTLY ON) + elseif (NOT BUILD_NACL_HELPER_BOOTSTRAP_WITH_CLANG) + set(BUILD_BOOTSTRAP_DIRECTLY ON) + endif() + + if (BUILD_BOOTSTRAP_DIRECTLY) + add_subdirectory(src/trusted/service_runtime/linux) + else() + if (CMAKE_GENERATOR MATCHES "Visual Studio") + set(BOOTSTRAP_GENERATOR "NMake Makefiles") + else() + set(BOOTSTRAP_GENERATOR "${CMAKE_GENERATOR}") + endif() + + find_program(CLANG_C_COMPILER NAMES "clang" DOC "Path to the Clang C compiler." REQUIRED) + find_program(CLANG_CXX_COMPILER NAMES "clang++" DOC "Path to the Clang C++ compiler." REQUIRED) + + if (NOT CLANG_TARGET) + execute_process(COMMAND "${CMAKE_CXX_COMPILER}" -dumpmachine + OUTPUT_VARIABLE CLANG_TARGET + OUTPUT_STRIP_TRAILING_WHITESPACE + # CMake 3.18.4 from Debian Buster doesn't support that option: + # COMMAND_ERROR_IS_FATAL ANY + ) + + if (NOT CLANG_TARGET) + message(FATAL_ERROR "Failed to read the compiler target.") + endif() + endif() + + foreach(inherited_option ${INHERITED_OPTIONS}) + list(APPEND INHERITED_OPTION_ARGS "-D${inherited_option}=${${inherited_option}}") + endforeach() + + set(BOOTSTRAP_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/nacl_helper_bootstrap-build") + + include(ExternalProject) + + ExternalProject_Add(nacl_helper_bootstrap-project + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + BINARY_DIR "${BOOTSTRAP_BUILD_DIR}" + CMAKE_GENERATOR "${BOOTSTRAP_GENERATOR}" + CMAKE_ARGS + "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" + "-DCMAKE_C_COMPILER=${CLANG_C_COMPILER}" + "-DCMAKE_CXX_COMPILER=${CLANG_CXX_COMPILER}" + "-DCMAKE_C_FLAGS=--target=${CLANG_TARGET}" + "-DCMAKE_CXX_FLAGS=--target=${CLANG_TARGET}" + -DBUILD_NACL_LOADER=OFF + -DBUILD_NACL_HELPER_BOOTSTRAP=ON + ${INHERITED_OPTION_ARGS} + # CMake 3.18.4 from Debian Buster doesn't support that option: + # INSTALL_BYPRODUCTS + INSTALL_COMMAND echo + ) + + add_custom_target(nacl_helper_bootstrap ALL + COMMAND "${CMAKE_COMMAND}" -E copy "${BOOTSTRAP_BUILD_DIR}/nacl_helper_bootstrap" + "${CMAKE_CURRENT_BINARY_DIR}/nacl_helper_bootstrap" + BYPRODUCTS + "${CMAKE_CURRENT_BINARY_DIR}/nacl_helper_bootstrap" + DEPENDS nacl_helper_bootstrap-project + ) + endif() +endif() diff --git a/cmake/DaemonPlatform/Architecture.cmake b/cmake/DaemonPlatform/Architecture.cmake new file mode 100644 index 0000000..03d2d48 --- /dev/null +++ b/cmake/DaemonPlatform/Architecture.cmake @@ -0,0 +1,121 @@ +# Daemon BSD Source Code +# Copyright (c) 2022, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +################################################################################ +# Determine architecture +################################################################################ + +# When adding a new architecture, look at all the places ARCH is used + +try_compile(BUILD_RESULT + "${CMAKE_BINARY_DIR}" + "${CMAKE_CURRENT_LIST_DIR}/Architecture/Architecture.cpp" + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + OUTPUT_VARIABLE BUILD_LOG +) + +# Setting -Werror in CXXFLAGS would produce errors instead of warning +# but that should not break the architecture detection, +# so we only print a CMake warning there and use BUILD_LOG content to +# detect unsupported platforms. +# Catching compilation error is still useful, for example to detect +# undefined types, missing header or things like that. +# Setting USE_WERROR to ON doesn't print this warning. +if (NOT BUILD_RESULT) + message(WARNING + "Failed to build Architecture.cpp\n" + "Setting -Werror in CXXFLAGS can produce false positive errors\n" + "${BUILD_LOG}" + ) +endif() + +string(REGEX MATCH "DAEMON_ARCH_([a-zA-Z0-9_]+)" ARCH_DEFINE "${BUILD_LOG}") +string(REPLACE "DAEMON_ARCH_" "" ARCH "${ARCH_DEFINE}") + +if (NOT ARCH) + message(FATAL_ERROR + "Missing DAEMON_ARCH, there is a mistake in Architecture.cpp\n" + "${BUILD_LOG}" + ) +else() + set(ARCH_${ARCH} ON) + + if(ARCH_unsupported) + message(FATAL_ERROR "Architecture not supported") + endif() +endif() + +message(STATUS "Detected architecture: ${ARCH}") + +add_definitions(-D${ARCH_DEFINE}) + +# This string can be modified without breaking compatibility. +daemon_add_buildinfo("char*" "DAEMON_ARCH_STRING" "\"${ARCH}\"") + +# Modifying NACL_ARCH breaks engine compatibility with nexe game binaries +# since NACL_ARCH contributes to the nexe file name. +set(NACL_ARCH "${ARCH}") +if (LINUX OR FREEBSD) + set(ARMHF_USAGE arm64 armel) + if (ARCH IN_LIST ARMHF_USAGE) + # Load 32-bit armhf nexe on 64-bit arm64 engine on Linux with multiarch. + # The nexe is system agnostic so there should be no difference with armel. + set(NACL_ARCH "armhf") + endif() +elseif(APPLE) + if ("${ARCH}" STREQUAL arm64) + # You can get emulated NaCl going like this: + # cp external_deps/macos-amd64-default_10/{nacl_loader,irt_core-amd64.nexe} build/ + set(NACL_ARCH "amd64") + endif() +endif() + +daemon_add_buildinfo("char*" "DAEMON_NACL_ARCH_STRING" "\"${NACL_ARCH}\"") + +option(USE_ARCH_INTRINSICS "Enable custom code using intrinsics functions or asm declarations" ON) +mark_as_advanced(USE_ARCH_INTRINSICS) + +macro(set_arch_intrinsics name) + if (USE_ARCH_INTRINSICS) + message(STATUS "Enabling ${name} architecture intrinsics") + add_definitions(-DDAEMON_USE_ARCH_INTRINSICS_${name}=1) + else() + message(STATUS "Disabling ${name} architecture intrinsics") + endif() +endmacro() + +if (USE_ARCH_INTRINSICS) + add_definitions(-DDAEMON_USE_ARCH_INTRINSICS=1) +endif() + +set_arch_intrinsics(${ARCH}) + +set(amd64_PARENT "i686") +set(arm64_PARENT "armhf") + +if (${ARCH}_PARENT) + set_arch_intrinsics(${${ARCH}_PARENT}) +endif() diff --git a/cmake/DaemonPlatform/Architecture/Architecture.cpp b/cmake/DaemonPlatform/Architecture/Architecture.cpp new file mode 100644 index 0000000..9c3a03b --- /dev/null +++ b/cmake/DaemonPlatform/Architecture/Architecture.cpp @@ -0,0 +1,118 @@ +/* +=========================================================================== +Daemon BSD Source Code +Copyright (c) 2022, Daemon Developers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================== +*/ + +/* The qprocessordetection.h file doesn't detect endianness for some +platforms including ppc64, but we know how to do it for them. */ + +#include + +/* This source file includes qprocessordetection.h from Qt: + +- https://github.com/qt/qtbase/blob/dev/src/corelib/global/qprocessordetection.h + https://raw.githubusercontent.com/qt/qtbase/dev/src/corelib/global/qprocessordetection.h + +Always update by downloading new version from Qt, do not edit by hand. + +This source file and the qprocessordetection.h header do not contribute to the +produced engine and game binaries in any way that can be subject to copyright. */ + +#include "qprocessordetection.h" + +/* The architecture names are loosely inspired by Debian conventions: + https://wiki.debian.org/ArchitectureSpecificsMemo + +Except we don't have the same technical debt so we don't have +to name i686 as i386 for backward compatibility purpose neither +care of platform name variants that are meant to distinguish +platform variants we cannot support anyway. */ + +/* PNaCl virtual machines. */ +#if defined(__native_client__) + #pragma message("DAEMON_ARCH_nacl") + +/* Wasm virtual machines, work in progress. */ +#elif defined(Q_PROCESSOR_WASM) + #pragma message("DAEMON_ARCH_wasm") + +/* Devices like: + - IBM PC compatibles and derivatives, + - Apple Intel-based mac, + - Steam Deck, Atari VCS consoles… */ + +#elif defined(Q_PROCESSOR_X86_64) + #pragma message("DAEMON_ARCH_amd64") + +#elif defined(Q_PROCESSOR_X86_32) + // Assume at least i686. Detecting older revisions would be unlikely to work here + // because the revisions are likely configured by flags, but this file is "compiled" + // without most command-line flags. + #pragma message("DAEMON_ARCH_i686") + +/* Devices like: + - Raspberry Pi, + - Apple M1-based mac, + - Android phones and tablets… */ + +#elif defined(Q_PROCESSOR_ARM_64) + #pragma message("DAEMON_ARCH_arm64") + +#elif defined(Q_PROCESSOR_ARM_32) && defined(__ARM_PCS_VFP) + #pragma message("DAEMON_ARCH_armhf") + +#elif defined(Q_PROCESSOR_ARM_32) && !defined(__ARM_PCS_VFP) + #pragma message("DAEMON_ARCH_armel") + +/* Devices like: + - Raptor Computing Systems Talos, Blackbird… */ + +#elif defined(Q_PROCESSOR_POWER_64) && Q_BYTE_ORDER == Q_BIG_ENDIAN + #pragma message("DAEMON_ARCH_ppc64") + +#elif defined(Q_PROCESSOR_POWER_64) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN + #pragma message("DAEMON_ARCH_ppc64el") + +/* 32-bit MIPS devices. */ +#elif defined(Q_PROCESSOR_MIPS) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN + #pragma message("DAEMON_ARCH_mipsel") + +/* Devices like: + - SiFive HiFive Unmatched, Horse Creek… */ + +#elif defined(Q_PROCESSOR_RISCV_64) + #pragma message("DAEMON_ARCH_riscv64") + +#else + #pragma message("DAEMON_ARCH_unknown") +#endif + +// Make the compilation succeeds if architecture is supported. +int main(int argc, char** argv) { + return 0; +} diff --git a/cmake/DaemonPlatform/Architecture/qprocessordetection.h b/cmake/DaemonPlatform/Architecture/qprocessordetection.h new file mode 100644 index 0000000..1b61391 --- /dev/null +++ b/cmake/DaemonPlatform/Architecture/qprocessordetection.h @@ -0,0 +1,390 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2016 Intel Corporation. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + + +#if 0 +#pragma qt_class(QtProcessorDetection) +#pragma qt_sync_skip_header_check +#pragma qt_sync_stop_processing +#endif + +#ifndef QPROCESSORDETECTION_H +#define QPROCESSORDETECTION_H + +/* + This file uses preprocessor #defines to set various Q_PROCESSOR_* #defines + based on the following patterns: + + Q_PROCESSOR_{FAMILY} + Q_PROCESSOR_{FAMILY}_{VARIANT} + Q_PROCESSOR_{FAMILY}_{REVISION} + + The first is always defined. Defines for the various revisions/variants are + optional and usually dependent on how the compiler was invoked. Variants + that are a superset of another should have a define for the superset. + + In addition to the processor family, variants, and revisions, we also set + Q_BYTE_ORDER appropriately for the target processor. For bi-endian + processors, we try to auto-detect the byte order using the __BIG_ENDIAN__, + __LITTLE_ENDIAN__, or __BYTE_ORDER__ preprocessor macros. + + Note: when adding support for new processors, be sure to update + config.tests/arch/arch.cpp to ensure that configure can detect the target + and host architectures. +*/ + +/* Machine byte-order, reuse preprocessor provided macros when available */ +#if defined(__ORDER_BIG_ENDIAN__) +# define Q_BIG_ENDIAN __ORDER_BIG_ENDIAN__ +#else +# define Q_BIG_ENDIAN 4321 +#endif +#if defined(__ORDER_LITTLE_ENDIAN__) +# define Q_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +#else +# define Q_LITTLE_ENDIAN 1234 +#endif + +/* + Alpha family, no revisions or variants + + Alpha is bi-endian, use endianness auto-detection implemented below. +*/ +// #elif defined(__alpha__) || defined(_M_ALPHA) +// # define Q_PROCESSOR_ALPHA +// Q_BYTE_ORDER not defined, use endianness auto-detection + +/* + ARM family, known revisions: V5, V6, V7, V8 + + ARM is bi-endian, detect using __ARMEL__ or __ARMEB__, falling back to + auto-detection implemented below. +*/ +#if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__) || defined(__ARM64__) +# if defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64) +# define Q_PROCESSOR_ARM_64 +# define Q_PROCESSOR_WORDSIZE 8 +# else +# define Q_PROCESSOR_ARM_32 +# endif +# if defined(__ARM_ARCH) && __ARM_ARCH > 1 +# define Q_PROCESSOR_ARM __ARM_ARCH +# elif defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM > 1 +# define Q_PROCESSOR_ARM __TARGET_ARCH_ARM +# elif defined(_M_ARM) && _M_ARM > 1 +# define Q_PROCESSOR_ARM _M_ARM +# elif defined(__ARM64_ARCH_8__) \ + || defined(__aarch64__) \ + || defined(__ARMv8__) \ + || defined(__ARMv8_A__) \ + || defined(_M_ARM64) +# define Q_PROCESSOR_ARM 8 +# elif defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7S__) \ + || defined(_ARM_ARCH_7) \ + || defined(__CORE_CORTEXA__) +# define Q_PROCESSOR_ARM 7 +# elif defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6M__) +# define Q_PROCESSOR_ARM 6 +# elif defined(__ARM_ARCH_5TEJ__) \ + || defined(__ARM_ARCH_5TE__) +# define Q_PROCESSOR_ARM 5 +# else +# define Q_PROCESSOR_ARM 0 +# endif +# if Q_PROCESSOR_ARM >= 8 +# define Q_PROCESSOR_ARM_V8 +# endif +# if Q_PROCESSOR_ARM >= 7 +# define Q_PROCESSOR_ARM_V7 +# endif +# if Q_PROCESSOR_ARM >= 6 +# define Q_PROCESSOR_ARM_V6 +# endif +# if Q_PROCESSOR_ARM >= 5 +# define Q_PROCESSOR_ARM_V5 +# else +# error "ARM architecture too old" +# endif +# if defined(__ARMEL__) || defined(_M_ARM64) +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# elif defined(__ARMEB__) +# define Q_BYTE_ORDER Q_BIG_ENDIAN +# else +// Q_BYTE_ORDER not defined, use endianness auto-detection +#endif + +/* + AVR32 family, no revisions or variants + + AVR32 is big-endian. +*/ +// #elif defined(__avr32__) +// # define Q_PROCESSOR_AVR32 +// # define Q_BYTE_ORDER Q_BIG_ENDIAN + +/* + Blackfin family, no revisions or variants + + Blackfin is little-endian. +*/ +// #elif defined(__bfin__) +// # define Q_PROCESSOR_BLACKFIN +// # define Q_BYTE_ORDER Q_LITTLE_ENDIAN + +/* + PA-RISC family, no revisions or variants + + PA-RISC is big-endian. +*/ +#elif defined(__hppa__) +# define Q_PROCESSOR_HPPA +# define Q_BYTE_ORDER Q_BIG_ENDIAN + +/* + X86 family, known variants: 32- and 64-bit + + X86 is little-endian. +*/ +#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define Q_PROCESSOR_X86_32 +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# define Q_PROCESSOR_WORDSIZE 4 + +/* + * We define Q_PROCESSOR_X86 == 6 for anything above a equivalent or better + * than a Pentium Pro (the processor whose architecture was called P6) or an + * Athlon. + * + * All processors since the Pentium III and the Athlon 4 have SSE support, so + * we use that to detect. That leaves the original Athlon, Pentium Pro and + * Pentium II. + */ + +# if defined(_M_IX86) +# define Q_PROCESSOR_X86 (_M_IX86/100) +# elif defined(__i686__) || defined(__athlon__) || defined(__SSE__) || defined(__pentiumpro__) +# define Q_PROCESSOR_X86 6 +# elif defined(__i586__) || defined(__k6__) || defined(__pentium__) +# define Q_PROCESSOR_X86 5 +# elif defined(__i486__) || defined(__80486__) +# define Q_PROCESSOR_X86 4 +# else +# define Q_PROCESSOR_X86 3 +# endif + +#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) +# define Q_PROCESSOR_X86 6 +# define Q_PROCESSOR_X86_64 +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# define Q_PROCESSOR_WORDSIZE 8 + +/* + Itanium (IA-64) family, no revisions or variants + + Itanium is bi-endian, use endianness auto-detection implemented below. +*/ +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) +# define Q_PROCESSOR_IA64 +# define Q_PROCESSOR_WORDSIZE 8 +// Q_BYTE_ORDER not defined, use endianness auto-detection + +/* + Motorola 68000 family, no revisions or variants + + M68K is big-endian. +*/ +#elif defined(__m68k__) +# define Q_PROCESSOR_M68K +# define Q_BYTE_ORDER Q_BIG_ENDIAN + +/* + MIPS family, known revisions: I, II, III, IV, 32, 64 + + MIPS is bi-endian, use endianness auto-detection implemented below. +*/ +#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000) +# define Q_PROCESSOR_MIPS +# if defined(_MIPS_ARCH_MIPS1) || (defined(__mips) && __mips - 0 >= 1) +# define Q_PROCESSOR_MIPS_I +# endif +# if defined(_MIPS_ARCH_MIPS2) || (defined(__mips) && __mips - 0 >= 2) +# define Q_PROCESSOR_MIPS_II +# endif +# if defined(_MIPS_ARCH_MIPS3) || (defined(__mips) && __mips - 0 >= 3) +# define Q_PROCESSOR_MIPS_III +# endif +# if defined(_MIPS_ARCH_MIPS4) || (defined(__mips) && __mips - 0 >= 4) +# define Q_PROCESSOR_MIPS_IV +# endif +# if defined(_MIPS_ARCH_MIPS5) || (defined(__mips) && __mips - 0 >= 5) +# define Q_PROCESSOR_MIPS_V +# endif +# if defined(_MIPS_ARCH_MIPS32) || defined(__mips32) || (defined(__mips) && __mips - 0 >= 32) +# define Q_PROCESSOR_MIPS_32 +# endif +# if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) +# define Q_PROCESSOR_MIPS_64 +# define Q_PROCESSOR_WORDSIZE 8 +# endif +# if defined(__MIPSEL__) +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# elif defined(__MIPSEB__) +# define Q_BYTE_ORDER Q_BIG_ENDIAN +# else +// Q_BYTE_ORDER not defined, use endianness auto-detection +# endif + +/* + Power family, known variants: 32- and 64-bit + + There are many more known variants/revisions that we do not handle/detect. + See http://en.wikipedia.org/wiki/Power_Architecture + and http://en.wikipedia.org/wiki/File:PowerISA-evolution.svg + + Power is bi-endian, use endianness auto-detection implemented below. +*/ +#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \ + || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \ + || defined(_M_MPPC) || defined(_M_PPC) +# define Q_PROCESSOR_POWER +# if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__) +# define Q_PROCESSOR_POWER_64 +# define Q_PROCESSOR_WORDSIZE 8 +# else +# define Q_PROCESSOR_POWER_32 +# endif +// Q_BYTE_ORDER not defined, use endianness auto-detection + +/* + RISC-V family, known variants: 32- and 64-bit + + RISC-V is little-endian. +*/ +#elif defined(__riscv) +# define Q_PROCESSOR_RISCV +# if __riscv_xlen == 64 +# define Q_PROCESSOR_RISCV_64 +# else +# define Q_PROCESSOR_RISCV_32 +# endif +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN + +/* + S390 family, known variant: S390X (64-bit) + + S390 is big-endian. +*/ +#elif defined(__s390__) +# define Q_PROCESSOR_S390 +# if defined(__s390x__) +# define Q_PROCESSOR_S390_X +# endif +# define Q_BYTE_ORDER Q_BIG_ENDIAN + +/* + SuperH family, optional revision: SH-4A + + SuperH is bi-endian, use endianness auto-detection implemented below. +*/ +// #elif defined(__sh__) +// # define Q_PROCESSOR_SH +// # if defined(__sh4a__) +// # define Q_PROCESSOR_SH_4A +// # endif +// Q_BYTE_ORDER not defined, use endianness auto-detection + +/* + SPARC family, optional revision: V9 + + SPARC is big-endian only prior to V9, while V9 is bi-endian with big-endian + as the default byte order. Assume all SPARC systems are big-endian. +*/ +#elif defined(__sparc__) +# define Q_PROCESSOR_SPARC +# if defined(__sparc_v9__) || defined(__sparcv9) +# define Q_PROCESSOR_SPARC_V9 +# endif +# if defined(__sparc64__) +# define Q_PROCESSOR_SPARC_64 +# endif +# define Q_BYTE_ORDER Q_BIG_ENDIAN + +// -- Web Assembly -- +#elif defined(__EMSCRIPTEN__) +# define Q_PROCESSOR_WASM +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# define Q_PROCESSOR_WORDSIZE 8 +#ifdef QT_COMPILER_SUPPORTS_SSE2 +# define Q_PROCESSOR_X86 6 // enables SIMD support +#endif + +#endif + +/* + NOTE: + GCC 4.6 added __BYTE_ORDER__, __ORDER_BIG_ENDIAN__, __ORDER_LITTLE_ENDIAN__ + and __ORDER_PDP_ENDIAN__ in SVN r165881. If you are using GCC 4.6 or newer, + this code will properly detect your target byte order; if you are not, and + the __LITTLE_ENDIAN__ or __BIG_ENDIAN__ macros are not defined, then this + code will fail to detect the target byte order. +*/ +// Some processors support either endian format, try to detect which we are using. +#if !defined(Q_BYTE_ORDER) +# if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == Q_BIG_ENDIAN || __BYTE_ORDER__ == Q_LITTLE_ENDIAN) +// Reuse __BYTE_ORDER__ as-is, since our Q_*_ENDIAN #defines match the preprocessor defaults +# define Q_BYTE_ORDER __BYTE_ORDER__ +# elif defined(__BIG_ENDIAN__) || defined(_big_endian__) || defined(_BIG_ENDIAN) +# define Q_BYTE_ORDER Q_BIG_ENDIAN +# elif defined(__LITTLE_ENDIAN__) || defined(_little_endian__) || defined(_LITTLE_ENDIAN) +# define Q_BYTE_ORDER Q_LITTLE_ENDIAN +# else +# error "Unable to determine byte order!" +# endif +#endif + +/* + Size of a pointer and the machine register size. We detect a 64-bit system by: + * GCC and compatible compilers (Clang, ICC on OS X and Windows) always define + __SIZEOF_POINTER__. This catches all known cases of ILP32 builds on 64-bit + processors. + * Most other Unix compilers define __LP64__ or _LP64 on 64-bit mode + (Long and Pointer 64-bit) + * If Q_PROCESSOR_WORDSIZE was defined above, it's assumed to match the pointer + size. + Otherwise, we assume to be 32-bit and then check in qglobal.cpp that it is right. +*/ + +#if defined __SIZEOF_POINTER__ +# define QT_POINTER_SIZE __SIZEOF_POINTER__ +#elif defined(__LP64__) || defined(_LP64) +# define QT_POINTER_SIZE 8 +#elif defined(Q_PROCESSOR_WORDSIZE) +# define QT_POINTER_SIZE Q_PROCESSOR_WORDSIZE +#else +# define QT_POINTER_SIZE 4 +#endif + +/* + Define Q_PROCESSOR_WORDSIZE to be the size of the machine's word (usually, + the size of the register). On some architectures where a pointer could be + smaller than the register, the macro is defined above. + + Falls back to QT_POINTER_SIZE if not set explicitly for the platform. +*/ +#ifndef Q_PROCESSOR_WORDSIZE +# define Q_PROCESSOR_WORDSIZE QT_POINTER_SIZE +#endif + + +#endif // QPROCESSORDETECTION_H diff --git a/cmake/DaemonPlatform/BuildInfo.cmake b/cmake/DaemonPlatform/BuildInfo.cmake new file mode 100644 index 0000000..a88e854 --- /dev/null +++ b/cmake/DaemonPlatform/BuildInfo.cmake @@ -0,0 +1,37 @@ +set(DAEMON_BUILDINFO_HEADER "// Automatically generated, do not modify!\n") +set(DAEMON_BUILDINFO_PARENT "${CMAKE_CURRENT_BINARY_DIR}/GeneratedSource") +set(DAEMON_BUILDINFO_DIR "DaemonBuildInfo") +set(DAEMON_BUILDINFO_DIR_FULLPATH "${DAEMON_BUILDINFO_PARENT}/${DAEMON_BUILDINFO_DIR}") +set(DAEMON_BUILDINFO_CPP_EXT ".cpp") +set(DAEMON_BUILDINFO_H_EXT ".h") +set(BUILDINFOLIST) + +file(MAKE_DIRECTORY "${DAEMON_BUILDINFO_DIR_FULLPATH}") +include_directories("${DAEMON_BUILDINFO_PARENT}") + +foreach(kind CPP H) + set(DAEMON_BUILDINFO_${kind} "${DAEMON_BUILDINFO_HEADER}") +endforeach() + +macro(daemon_add_buildinfo TYPE NAME VALUE) + set(DAEMON_BUILDINFO_CPP "${DAEMON_BUILDINFO_CPP}const ${TYPE} ${NAME}=${VALUE};\n") + set(DAEMON_BUILDINFO_H "${DAEMON_BUILDINFO_H}extern const ${TYPE} ${NAME};\n") +endmacro() + +macro(daemon_write_buildinfo NAME) + foreach(kind CPP H) + set(DAEMON_BUILDINFO_${kind}_NAME "${NAME}${DAEMON_BUILDINFO_${kind}_EXT}") + set(DAEMON_BUILDINFO_${kind}_FILE "${DAEMON_BUILDINFO_DIR}/${DAEMON_BUILDINFO_${kind}_NAME}") + set(DAEMON_BUILDINFO_${kind}_FILE_FULLPATH "${DAEMON_BUILDINFO_PARENT}/${DAEMON_BUILDINFO_${kind}_FILE}") + list(APPEND BUILDINFOLIST "${DAEMON_BUILDINFO_${kind}_FILE_FULLPATH}") + + if (EXISTS "${DAEMON_BUILDINFO_${kind}_FILE_FULLPATH}") + file(READ "${DAEMON_BUILDINFO_${kind}_FILE_FULLPATH}" DAEMON_BUILDINFO_${kind}_READ) + endif() + + if (NOT "${DAEMON_BUILDINFO_${kind}}" STREQUAL "${DAEMON_BUILDINFO_${kind}_READ}") + message(STATUS "Generating ${DAEMON_BUILDINFO_${kind}_FILE}") + file(WRITE "${DAEMON_BUILDINFO_${kind}_FILE_FULLPATH}" "${DAEMON_BUILDINFO_${kind}}") + endif() + endforeach() +endmacro() diff --git a/cmake/DaemonPlatform/Compiler.cmake b/cmake/DaemonPlatform/Compiler.cmake new file mode 100644 index 0000000..43765fd --- /dev/null +++ b/cmake/DaemonPlatform/Compiler.cmake @@ -0,0 +1,241 @@ +# Daemon BSD Source Code +# Copyright (c) 2024, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +################################################################################ +# Determine compiler +################################################################################ + +# FIXME: Force -W#pragma-messages and -Wno-error +# In case there is -Wno-#pragma-messages or -Werror in CFLAGS/CXXFLAGS + +function(detect_daemon_compiler lang) + set(C_NAME "C") + set(CXX_NAME "C++") + set(C_EXT ".c") + set(CXX_EXT ".cpp") + + try_compile(BUILD_RESULT + "${CMAKE_BINARY_DIR}" + "${CMAKE_CURRENT_LIST_DIR}/Compiler/Compiler${${lang}_EXT}" + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + OUTPUT_VARIABLE BUILD_LOG + ) + + get_filename_component(compiler_basename "${CMAKE_${lang}_COMPILER}" NAME) + + if (NOT BUILD_RESULT) + message(WARNING "Failed to build DaemonCompiler${${lang}_EXT}, relying on CMake builtin detection.") + set(compiler_name "Unknown") + else() + set(BUILD_LOG "\n${BUILD_LOG}\n") + string(REGEX REPLACE "\n[^\n]*REPORT>[^\n]*\n" "\n" BUILD_LOG "${BUILD_LOG}") + + string(REGEX REPLACE ".*\nDAEMON_COMPILER_NAME=([^\n]*)\n.*" "\\1" + compiler_name "${BUILD_LOG}") + + foreach(name GCC;Clang;generic;${compiler_name}) + set(compatibility_regex ".*\nDAEMON_COMPILER_${name}_COMPATIBILITY=([^\n]*)\n.*") + if ("${BUILD_LOG}" MATCHES ${compatibility_regex}) + string(REGEX REPLACE ${compatibility_regex} "\\1" + compiler_${name}_compatibility "${BUILD_LOG}") + endif() + + set(version_regex ".*\nDAEMON_COMPILER_${name}_VERSION=([^\n]*)\n.*") + if ("${BUILD_LOG}" MATCHES ${version_regex}) + string(REGEX REPLACE ${version_regex} "\\1" + compiler_${name}_version "${BUILD_LOG}") + endif() + + set(version_string_regex ".*\nDAEMON_COMPILER_${name}_VERSION_STRING=([^\n]*)\n.*") + if ("${BUILD_LOG}" MATCHES ${version_string_regex}) + string(REGEX REPLACE ${version_string_regex} "\\1" + compiler_${name}_version_string "${BUILD_LOG}") + endif() + + set(DAEMON_${lang}_COMPILER_${name}_VERSION + "${compiler_${name}_version}" + PARENT_SCOPE) + + set(DAEMON_${lang}_COMPILER_${name}_COMPATIBILITY + "${compiler_${name}_compatibility}" + PARENT_SCOPE) + endforeach() + endif() + + if (compiler_name STREQUAL "Unknown") + if (CMAKE_${lang}_COMPILER_ID) + set(compiler_name "${CMAKE_${lang}_COMPILER_ID}") + # Compiler version is done below. + else() + message(WARNING "Unknown ${${lang}_NAME} compiler") + endif() + endif() + + # AOCC + if (compiler_Clang_version_string) + set(aocc_version_regex ".*CLANG: AOCC_([^ )]+).*") + if (compiler_Clang_version_string MATCHES ${aocc_version_regex}) + set(compiler_name "AOCC") + string(REGEX REPLACE ${aocc_version_regex} "\\1" + compiler_AOCC_version "${compiler_Clang_version_string}") + string(REGEX REPLACE "(.*)-Build.*" "\\1" + compiler_AOCC_version "${compiler_AOCC_version}") + endif() + endif() + + # Zig + if (compiler_Clang_version_string) + set(zig_version_regex ".*[(]https://github.com/ziglang/zig-bootstrap .*[)]") + if (compiler_Clang_version_string MATCHES ${zig_version_regex}) + set(compiler_name "Zig") + endif() + + # Parse “zig version” + execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" version + OUTPUT_VARIABLE CUSTOM_${lang}_ZIG_OUTPUT + RESULT_VARIABLE CUSTOM_${lang}_ZIG_RETURN_CODE + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if (NOT CUSTOM_${lang}_ZIG_RETURN_CODE) # Success + set(compiler_Zig_version "${CUSTOM_${lang}_ZIG_OUTPUT}") + endif() + endif() + + # Compilers that use underlying Clang version as their own version. + foreach(name in AppleClang) + if (compiler_name STREQUAL "${name}") + set(compiler_${name}_version "${compiler_Clang_version}") + endif() + endforeach() + + # Compilers that write the version number at the beginning of the VERSION string. + set(string_version_regex "([^ ]+).*") + foreach(name in PNaCl) + if (compiler_name STREQUAL "${name}") + if (compiler_generic_version_string) + if (compiler_generic_version_string MATCHES ${string_version_regex}) + string(REGEX REPLACE ${string_version_regex} "\\1" + compiler_${name}_version "${compiler_generic_version_string}") + endif() + endif() + endif() + endforeach() + + if (compiler_ARMClang_version_string) + # There is no __armclang_patchlevel__ so we should parse __armclang_version__ to get it. + if (compiler_ARMClang_version_string MATCHES ${string_version_regex}) + string(REGEX REPLACE ${string_version_regex} "\\1" + compiler_ARMClang_version "${compiler_ARMClang_version_string}") + endif() + endif() + + if (compiler_ICX_version) + # 20240000 becomes 2024.0.0 + string(REGEX REPLACE "(....)(..)(..)" "\\1.\\2.\\3" + compiler_ICX_version "${compiler_ICX_version}") + string(REGEX REPLACE "\\.0" "." + compiler_ICX_version "${compiler_ICX_version}") + endif() + + if (compiler_${compiler_name}_version) + set(compiler_version "${compiler_${compiler_name}_version}") + elseif (CMAKE_${lang}_COMPILER_VERSION) + set(compiler_version "${CMAKE_${lang}_COMPILER_VERSION}") + else() + set(compiler_version "Unknown") + message(WARNING "Unknown ${${lang}_NAME} compiler version") + endif() + + set(DAEMON_${lang}_COMPILER_BASENAME "${compiler_basename}" PARENT_SCOPE) + set(DAEMON_${lang}_COMPILER_NAME "${compiler_name}" PARENT_SCOPE) + set(DAEMON_${lang}_COMPILER_VERSION "${compiler_version}" PARENT_SCOPE) +endfunction() + +message(STATUS "CMake generator: ${CMAKE_GENERATOR}") + +foreach(lang C;CXX) + set(C_NAME "C") + set(CXX_NAME "C++") + + if (MSVC) + # Let CMake do the job, it does it very well, + # and there is probably no variant to take care about. + set(DAEMON_${lang}_COMPILER_NAME "${CMAKE_${lang}_COMPILER_ID}") + set(DAEMON_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}") + get_filename_component(DAEMON_${lang}_COMPILER_BASENAME "${CMAKE_${lang}_COMPILER}" NAME) + else() + detect_daemon_compiler(${lang}) + + if (DAEMON_${lang}_COMPILER_Clang_COMPATIBILITY) + if (NOT DAEMON_${lang}_COMPILER_NAME STREQUAL "Clang") + set(DAEMON_${lang}_COMPILER_EXTENDED_VERSION + "${DAEMON_${lang}_COMPILER_VERSION}/Clang_${DAEMON_${lang}_COMPILER_Clang_VERSION}") + endif() + elseif (DAEMON_${lang}_COMPILER_GCC_COMPATIBILITY) + if (NOT DAEMON_${lang}_COMPILER_NAME STREQUAL "GCC") + # Almost all compilers on Earth pretend to be GCC compatible. + # So we first have to check it's really a GCC variant. + # Parse “ -v” + execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -v + ERROR_VARIABLE CUSTOM_${lang}_GCC_OUTPUT + RESULT_VARIABLE CUSTOM_${lang}_GCC_RETURN_CODE + OUTPUT_QUIET) + + if (NOT CUSTOM_${lang}_GCC_RETURN_CODE) # Success + # The existence of this string tells us it's a GCC variant. + # The version in this string is the same as __VERSION__, + # the version of the GCC variant, not the version of the upstream + # GCC we are looking for. + if ("${CUSTOM_${lang}_GCC_OUTPUT}" MATCHES "\ngcc version ") + set(DAEMON_${lang}_COMPILER_EXTENDED_VERSION + "${DAEMON_${lang}_COMPILER_VERSION}/GCC_${DAEMON_${lang}_COMPILER_GCC_VERSION}") + endif() + endif() + endif() + endif() + endif() + + if (NOT DAEMON_${lang}_COMPILER_EXTENDED_VERSION) + set(DAEMON_${lang}_COMPILER_EXTENDED_VERSION "${DAEMON_${lang}_COMPILER_VERSION}") + endif() + + set(DAEMON_${lang}_COMPILER_STRING + "${DAEMON_${lang}_COMPILER_NAME}_${DAEMON_${lang}_COMPILER_EXTENDED_VERSION}:${DAEMON_${lang}_COMPILER_BASENAME}") + + if (CMAKE_CXX_COMPILER_ARG1) + set(DAEMON_${lang}_COMPILER_STRING "${DAEMON_${lang}_COMPILER_STRING}:${CMAKE_CXX_COMPILER_ARG1}") + endif() + + message(STATUS "Detected ${${lang}_NAME} compiler: ${DAEMON_${lang}_COMPILER_STRING}") + + set(compiler_var_name "DAEMON_${lang}_COMPILER_${DAEMON_${lang}_COMPILER_NAME}") + set(${compiler_var_name} ON) + add_definitions(-D${compiler_var_name}=1) + + daemon_add_buildinfo("char*" "DAEMON_${lang}_COMPILER_STRING" "\"${DAEMON_${lang}_COMPILER_STRING}\"") +endforeach() diff --git a/cmake/DaemonPlatform/Compiler/Compiler.c b/cmake/DaemonPlatform/Compiler/Compiler.c new file mode 100644 index 0000000..f05c095 --- /dev/null +++ b/cmake/DaemonPlatform/Compiler/Compiler.c @@ -0,0 +1,165 @@ +/* +=========================================================================== +Daemon BSD Source Code +Copyright (c) 2024, Daemon Developers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================== +*/ + +#define STRING(s) #s +#define XSTRING(s) STRING(s) + +#define REPORT(key, value) \ + "REPORT>" +#define REPORT_VERSION_3(name, major, minor, patch) \ + REPORT(name "_VERSION", XSTRING(major) "." XSTRING(minor) "." XSTRING(patch)) +#define REPORT_VERSION_2(name, major, minor) \ + REPORT(name "_VERSION", XSTRING(major) "." XSTRING(minor)) +#define REPORT_VERSION_1(name, major) \ + REPORT(name "_VERSION", XSTRING(major)) +#define REPORT_VERSION_STRING(name, value) \ + REPORT(name "_VERSION_STRING", value) +#define REPORT_COMPATIBILITY(name) \ + REPORT(name "_COMPATIBILITY", "ON") +#define REPORT_NAME(name) \ + REPORT("NAME", name) + +// GCC + +#if defined(__GNUC__) + #pragma message(REPORT_COMPATIBILITY("GCC")) +#endif + +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) + #pragma message(REPORT_VERSION_3("GCC", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)) +#endif + +// Clang + +#if defined(__clang__) + #pragma message(REPORT_COMPATIBILITY("Clang")) +#endif + +#if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) + #pragma message(REPORT_VERSION_3("Clang", __clang_major__, __clang_minor__, __clang_patchlevel__)) +#endif + +#if defined(__clang_version__) + #pragma message(REPORT_VERSION_STRING("Clang", __clang_version__)) +#endif + +// ICC + +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) + #pragma message(REPORT_VERSION_2("ICC", __INTEL_COMPILER, __INTEL_COMPILER_UPDATE)) +#elif defined(_ICC) + #pragma message(REPORT_VERSION_1("ICC", __ICC)) +#endif + +// ICX + +#if defined(__INTEL_CLANG_COMPILER) + // This requires extra parsing since it's in the form 20240000 for 2024.0.0. + #pragma message(REPORT_VERSION_1("ICX", __INTEL_CLANG_COMPILER)) +#elif defined(__INTEL_LLVM_COMPILER) + // This requires extra parsing since it's in the form 20240000 for 2024.0.0. + #pragma message(REPORT_VERSION_1("ICX", __INTEL_LLVM_COMPILER)) +#endif + +// ArmClang + +#if defined(__armclang_major__) && defined(__armclang_minor__) + // There is no __armclang_patchlevel__, 23.04.1 is reported as 23.04. + #pragma message(REPORT_VERSION_2("ARMClang", __armclang_major__, __armclang_minor__)) +#endif + +#if defined(__armclang_version__) + // This string contains the version patch level and requires extra parsing. + // #define __armclang_major__ 23 + // #define __armclang_minor__ 04 + // #define __armclang_version__ "23.04.1 (build number 14)" + #pragma message(REPORT_VERSION_STRING("ARMClang", __armclang_version__)) +#endif + +// Generic + +#if defined(__VERSION__) + #pragma message(REPORT_VERSION_STRING("generic", __VERSION__)) +#endif + +// Selection + +// There is no Zig specific version definition, we can detect its usage by parsing +// other definitions, and then use the `zig version` command to get the version: +// #define __VERSION__ "Clang 18.1.6 (https://github.com/ziglang/zig-bootstrap 98bc6bf4fc4009888d33941daf6b600d20a42a56)" +// #define __clang_version__ "18.1.6 (https://github.com/ziglang/zig-bootstrap 98bc6bf4fc4009888d33941daf6b600d20a42a56)" + +// There is no Saigo specific version definition, we reuse the clang version instead +// of parsing the version strings: +// #define __VERSION__ "Clang 19.0.0git (https://chromium.googlesource.com/a/native_client/nacl-llvm-project-v10.git e25355fddbdece2ef08747ead05b7f69f3bc6dca)" +// #define __clang_version__ "19.0.0git (https://chromium.googlesource.com/a/native_client/nacl-llvm-project-v10.git e25355fddbdece2ef08747ead05b7f69f3bc6dca)" + +// There is no PNaCl specific version definition, we should parse another definition: +// #define __VERSION__ "4.2.1 Compatible Clang 3.6.0 (https://chromium.googlesource.com/a/native_client/pnacl-clang.git 96b3da27dcefc9d152e51cf54280989b2206d789) (https://chromium.googlesource.com/a/native_client/pnacl-llvm.git d0089f0b008e03cfd141f05c80e3b628c2df75c1)" + +// There is no AOCC specific version definition, we should parse another definition: +// #define __VERSION__ "AMD Clang 14.0.6 (CLANG: AOCC_4.0.0-Build#434 2022_10_28)" +// #define __clang_version__ "14.0.6 (CLANG: AOCC_4.0.0-Build#434 2022_10_28)" + +// There is no usable AppleClang version definitions, +// It reports an old GCC version but reuses the LLVM version as its owns: +// #define __GNUC__ 4.2.1 +// #define __APPLE_CC_ 6000 +// #define __apple_build_version__ 10010046 +// #define __VERSION__ "4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.46.4)" + +#if defined(__INTEL_COMPILER) || defined(__ICC) + #pragma message(REPORT_NAME("ICC")) // Intel +#elif defined(__INTEL_CLANG_COMPILER) || defined(__INTEL_LLVM_COMPILER) + #pragma message(REPORT_NAME("ICX")) // IntelLLVM +#elif defined(__wasi__) + #pragma message(REPORT_NAME("WASI")) +#elif defined(__saigo__) + #pragma message(REPORT_NAME("Saigo")) +#elif defined(__pnacl__) + #pragma message(REPORT_NAME("PNaCl")) +#elif defined(__MINGW64__) || defined(__MINGW32__) + #pragma message(REPORT_NAME("MinGW")) +#elif defined(__armclang_major__) || defined(__armclang_version__) + #pragma message(REPORT_NAME("ARMClang")) +#elif defined(__clang__) && (defined(__APPLE_CC__) || defined(__apple_build_version__)) + #pragma message(REPORT_NAME("AppleClang")) +#elif defined(__clang__) + #pragma message(REPORT_NAME("Clang")) +#elif defined(__GNUC__) + #pragma message(REPORT_NAME("GCC")) // GNU +#else + #pragma message(REPORT_NAME("Unknown")) +#endif + +// Make the compilation succeeds if architecture is supported. +int main(int argc, char** argv) { + return 0; +} diff --git a/cmake/DaemonPlatform/Compiler/Compiler.cpp b/cmake/DaemonPlatform/Compiler/Compiler.cpp new file mode 100644 index 0000000..41c3f57 --- /dev/null +++ b/cmake/DaemonPlatform/Compiler/Compiler.cpp @@ -0,0 +1 @@ +#include "Compiler.c" diff --git a/cmake/DaemonPlatform/Compiler/Compiler.sh b/cmake/DaemonPlatform/Compiler/Compiler.sh new file mode 100755 index 0000000..e7ba168 --- /dev/null +++ b/cmake/DaemonPlatform/Compiler/Compiler.sh @@ -0,0 +1,49 @@ +#! /usr/bin/env bash + +# Daemon BSD Source Code +# Copyright (c) 2024, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Test script not used by the CMake build system. Usage example: +# ./DaemonCompiler.sh gcc + +set -ueo pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +file_path="${script_dir}/Compiler.c" + +# PNaCl doesn't work with “-o /dev/null” as it uses the output path as a +# pattern for temporary files and then the parent folder should be writable. +# Zig caches the build if both the source and the output don't change. Since +# the /dev/null file never changes, Zig skips the compilation once done once. +# So we need to use a randomly named path in a writable directory. +temp_file="$(mktemp)" + +"${@}" "${file_path}" -o "${temp_file}" 2>&1 \ + | grep 'REPORT>.*//' \ +|| "${@}" "${file_path}" -o "${temp_file}" + +rm "${temp_file}" diff --git a/cmake/DaemonPlatform/Platform.cmake b/cmake/DaemonPlatform/Platform.cmake new file mode 100644 index 0000000..2ebc15d --- /dev/null +++ b/cmake/DaemonPlatform/Platform.cmake @@ -0,0 +1,12 @@ +include(${CMAKE_CURRENT_LIST_DIR}/BuildInfo.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/System.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/Architecture.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/Compiler.cmake) + +if (NACL AND DAEMON_COMPILER_saigo) + # Saigo clang reports weird errors when building some Unvanquished cgame and sgame arm nexe with PIE. + # Saigo clang crashes when building Unvanquished amd64 cgame with PIE, sgame builds properly though. + set(NACL_PIE 0) +else() + set(NACL_PIE 1) +endif() diff --git a/cmake/DaemonPlatform/System.cmake b/cmake/DaemonPlatform/System.cmake new file mode 100644 index 0000000..4d4a928 --- /dev/null +++ b/cmake/DaemonPlatform/System.cmake @@ -0,0 +1,44 @@ +# Daemon BSD Source Code +# Copyright (c) 2013-2016, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +################################################################################ +# Determine platform +################################################################################ + +# When adding a new platform, look at all the places WIN32, APPLE and LINUX are used +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + set(LINUX ON) +elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + set(FREEBSD ON) +elseif(ANDROID) + # Use the same code as Linux unless there is an explicit test for Android. + set(LINUX ON) +elseif(WIN32) +elseif(APPLE) +elseif(NACL) +else() + message(FATAL_ERROR "Platform not supported") +endif() diff --git a/cmake/NaClFlags.cmake b/cmake/NaClFlags.cmake new file mode 100644 index 0000000..5a60620 --- /dev/null +++ b/cmake/NaClFlags.cmake @@ -0,0 +1,316 @@ +option(USE_WERROR "Tell the compiler to make the build fail when warnings are present." OFF) + +if (NOT MSVC) + option(USE_STATIC_LIBS "Tries to use static libs where possible." OFF) +endif() + +if (ARCH_armhf) + option(USE_ARMHF_16K_PAGESIZE "Build armhf binaries with 16K PageSize." OFF) + list(APPEND INHERITED_OPTIONS "USE_ARMHF_16K_PAGESIZE") +endif() + +macro(set_ASM_flag FLAG) + set(lang ASM) + if (${ARGC} GREATER 1) + set(CMAKE_${lang}_FLAGS_${ARGV1} "${CMAKE_${lang}_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${FLAG}") + endif() +endmacro() + +macro(set_C_flag FLAG) + set(lang C) + if (${ARGC} GREATER 1) + set(CMAKE_${lang}_FLAGS_${ARGV1} "${CMAKE_${lang}_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${FLAG}") + endif() +endmacro() + +macro(set_CXX_flag FLAG) + set(lang CXX) + if (${ARGC} GREATER 1) + set(CMAKE_${lang}_FLAGS_${ARGV1} "${CMAKE_${lang}_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${FLAG}") + endif() +endmacro() + +macro(set_compiler_flag FLAG) + foreach(lang C CXX ASM) + if (${ARGC} GREATER 1) + set(CMAKE_${lang}_FLAGS_${ARGV1} "${CMAKE_${lang}_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS} ${FLAG}") + endif() + endforeach() +endmacro() + +macro(set_EXE_linker_flag FLAG) + set(kind EXE) + if (${ARGC} GREATER 1) + set(CMAKE_${kind}_LINKER_FLAGS_${ARGV1} "${CMAKE_${kind}_LINKER_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${kind}_LINKER_FLAGS "${CMAKE_${kind}_LINKER_FLAGS} ${FLAG}") + endif() +endmacro() + +macro(set_SHARED_linker_flag FLAG) + set(kind SHARED) + if (${ARGC} GREATER 1) + set(CMAKE_${kind}_LINKER_FLAGS_${ARGV1} "${CMAKE_${kind}_LINKER_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${kind}_LINKER_FLAGS "${CMAKE_${kind}_LINKER_FLAGS} ${FLAG}") + endif() +endmacro() + +macro(set_MODULE_linker_flag FLAG) + set(kind MODULE) + if (${ARGC} GREATER 1) + set(CMAKE_${kind}_LINKER_FLAGS_${ARGV1} "${CMAKE_${kind}_LINKER_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${kind}_LINKER_FLAGS "${CMAKE_${kind}_LINKER_FLAGS} ${FLAG}") + endif() +endmacro() + +macro(set_DLL_linker_flag FLAG) + foreach(kind SHARED MODULE) + if (${ARGC} GREATER 1) + set(CMAKE_${kind}_LINKER_FLAGS_${ARGV1} "${CMAKE_${kind}_LINKER_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${kind}_LINKER_FLAGS "${CMAKE_${kind}_LINKER_FLAGS} ${FLAG}") + endif() + endforeach() +endmacro() + +macro(set_linker_flag FLAG) + foreach(kind EXE SHARED MODULE) + if (${ARGC} GREATER 1) + set(CMAKE_${kind}_LINKER_FLAGS_${ARGV1} "${CMAKE_${kind}_LINKER_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_${kind}_LINKER_FLAGS "${CMAKE_${kind}_LINKER_FLAGS} ${FLAG}") + endif() + endforeach() +endmacro() + +if (USE_STATIC_LIBS) + set_compiler_flag("-static") + set_linker_flag("-static") +endif() + +if (USE_ARMHF_16K_PAGESIZE) + set_linker_flag("-Wl,-z,max-page-size=16384") +endif() + +#TODO: Import from SetUpClang() from (root)/SConstruct. +#TODO: This is mostly ASAN configurations. + +# From MakeUnixLikeEnv() from (root)/SConstruct. +if (LINUX OR APPLE OR MINGW) + set_C_flag("-std=gnu99") + # -Wdeclaration-after-statement is desirable because MS studio does + # not allow declarations after statements in a block, and since much + # of our code is portable and primarily initially tested on Linux, + # it'd be nice to get the build error earlier rather than later + # (building and testing on Linux is faster). + # TODO(nfullagar): should we consider switching to -std=c99 ? + set_C_flag("-Wdeclaration-after-statement") + # Require defining functions as "foo(void)" rather than + # "foo()" because, in C (but not C++), the latter defines a + # function with unspecified arguments rather than no + # arguments. + set_C_flag("-Wstrict-prototypes") + + # set_compiler_flag("-malign-double") + set_compiler_flag("-Wall") + set_compiler_flag("-pedantic") + set_compiler_flag("-Wextra") + set_compiler_flag("-Wno-long-long") + set_compiler_flag("-Wswitch-enum") + set_compiler_flag("-Wsign-compare") + set_compiler_flag("-Wundef") + set_compiler_flag("-fdiagnostics-show-option") + set_compiler_flag("-fvisibility=hidden") + set_compiler_flag("-fstack-protector") + + # NOTE: pthread is only neeeded for libppNaClPlugin.so and on arm +#TODO: LIBS = ['pthread'] + + add_definitions(-D__STDC_LIMIT_MACROS=1) + add_definitions(-D__STDC_FORMAT_MACROS=1) + + if (NOT ANDROID) + set_CXX_flag("-std=c++98") + endif() + + if (NOT DAEMON_CXX_COMPILER_Clang_COMPATIBILITY) + set_compiler_flag("--param ssp-buffer-size=4") + endif() + + if (USE_WERROR) + # It was only set on linker flag in (root)SConstruct. + set_linker_flag("-Werror") + endif() +endif() + +# From MakeWindowsEnv() from (root)/SConstruct. +if (WIN32) + # Windows /SAFESEH linking requires either an .sxdata section be + # present or that @feat.00 be defined as a local, absolute symbol + # with an odd value. +#TODO: ASCOM = ('$ASPPCOM /E /D__ASSEMBLER__ | ' +#TODO: '$WINASM -defsym @feat.00=1 -o $TARGET'), + add_definitions("-D_WIN32_WINNT=0x0501") + add_definitions("-D__STDC_LIMIT_MACROS=1") + add_definitions("-DNOMINMAX=1") + # WIN32 is used by ppapi + add_definitions("-DWIN32=1") + # WIN32_LEAN_AND_MEAN tells windows.h to omit obsolete and rarely + # used #include files. This allows use of Winsock 2.0 which otherwise + # would conflict with Winsock 1.x included by windows.h. + add_definitions("-DWIN32_LEAN_AND_MEAN=1") + + if (MSVC) + # TODO(bsy) remove 4355 once cross-repo + # NACL_ALLOW_THIS_IN_INITIALIZER_LIST changes go in. + set_compiler_flag("/EHsc") + set_compiler_flag("/Wx") + set_compiler_flag("/wd4355") + set_compiler_flag("/wd4800") + + if (ARCH_i686) + # This linker option allows us to ensure our builds are compatible with + # Chromium, which uses it. +#TODO: disabled until ASCOM is configured. +#TODO: set_linker_flag("safeseh") + endif() + + # We use the GNU assembler (gas) on Windows so that we can use the + # same .S assembly files on all platforms. Microsoft's assembler uses + # a completely different syntax for x86 code. +#FIXME: Use x86_64-w64-mingw32-as.exe or x86_64-w32-mingw32-as.exe on MSVC for .S files. + endif() +endif() + +# From MakeMacEnv() from (root)/SConstruct. +if (APPLE) + set(MAC_DEPLOYMENT_TARGET "10.6") + set(MAC_SDK_FLAG "-mmacosx-version-min=${MAC_DEPLOYMENT_TARGET}") + + set_compiler_flag(${MAC_SDK_FLAG}) + set_linker_flag(${MAC_SDK_FLAG}) + + set_compiler_flag("-fPIC") + set_linker_flag("-fPIC") + set_compiler_flag("-Wno-gnu") + set_linker_flag("-stdlib=libc++") +endif() + +# From SetUpLinuxEnvArm() from (root)/SConstruct. +if (LINUX AND ARCH_armhf) + # The -rpath-link argument is needed on Ubuntu/Precise to + # avoid linker warnings about missing ld.linux.so.3. + # TODO(sbc): remove this once we stop supporting Precise + # as a build environment. + # We (Dæmon) don't support Precise. + # set_linker_flag("-fuse-ld=lld") + + if (DAEMON_CXX_COMPILER_Clang_COMPATIBILITY) + # If ARCH is "armhf", then the target is already set properly by the toolchain. + # set_compiler_flag("--target=arm-linux-gnueabihf") + # set_linker_flag("--target=arm-linux-gnueabihf") + endif() + + set_compiler_flag("-march=armv7-a") + set_compiler_flag("-mtune=generic-armv7-a") + set_compiler_flag("-mfpu=neon") + # If ARCH is "armhf", then the float ABI is already set properly by the toolchain. + # set_compiler_flag("-mfloat-abi=hard") +endif() + +# Partially from SetUpAndroidEnv() from (root)/SConstruct. +if (LINUX AND ARCH_armel) + set_compiler_flag("-march=armv7-a") + set_compiler_flag("-mfpu=vfp") + set_compiler_flag("-mfloat-abi=softfp") +endif() + +#TODO: Import from SetUpAndroidEnv() from (root)/SConstruct. +if (ANDROID) +#TODO: LIBS=['stlport_shared', +#TODO: 'gcc', +#TODO: 'c', +#TODO: 'dl', +#TODO: 'm', +#TODO: ], + +#TODO: env.Append(CCFLAGS=[ +#TODO: '-I%s' % android_stlport_include, +#TODO: CXXFLAGS=['-I%s' % android_stlport_include, +#TODO: '-I%s' % android_ndk_include, + + # (root)/SConstruct was just setting -DANDROID without any value. + # set_compiler_definition("-DANDROID") + # The compiler sets it, we better trust it. + # set_compiler_definition("-D__ANDROID__") + + set_compiler_flag("-ffunction-sections") + set_compiler_flag("-g") + set_compiler_flag("-fstack-protector") + set_compiler_flag("-fno-short-enums") + set_compiler_flag("-finline-limit=64") + set_compiler_flag("-Wa,--noexecstack") + # Due to bogus warnings on uintptr_t formats. + set_compiler_flag("-Wno-format") + + set_CXX_flag("-fno-exceptions") + + # Copied from (root)SConsctruct, break build in Termux, + # produces undefined symbols in std::string. + # set_linker_flag("-nostdlib") + + set_linker_flag("-Wl,--no-undefined") + # Don't export symbols from statically linked libraries. + set_linker_flag("-Wl,--exclude-libs=ALL") + + # crtbegin_dynamic.o should be the last item in ldflags. + # Already done by the toolchain, same for crtend_android.o. + # crtbegin_so.o should be the last item in ldflags. + # Already done by the toolchain, same for crtend_so.o. +endif() + +# From SetUpLinuxEnvMips() from (root)/SConstruct. +if (LINUX AND ARCH_mipsel) +#TODO: env.Append(LIBS=['rt', 'dl', 'pthread'] + set_compiler_flag("-march=mips32r2") + # Because of: + # src/trusted/service_runtime/arch/mips/nacl_switch.S: Assembler messages: + # src/trusted/service_runtime/arch/mips/nacl_switch.S:38: Error: float register should be even, was 1 + # src/trusted/service_runtime/arch/mips/nacl_switch.S:72: Error: float register should be even, was 1 + set_compiler_flag("-mfp32") +endif() + +# From MakeGenericLinuxEnv() from (root)/SConstruct. +if (LINUX) + add_definitions(-D_POSIX_C_SOURCE=199506) + add_definitions(-D_XOPEN_SOURCE=600) + add_definitions(-D_GNU_SOURCE=1) + add_definitions(-D_FORTIFY_SOURCE=2) + + if (NOT ANDROID) + # Disabled in (root)/SConstruct. + add_definitions(-D_LARGEFILE64_SOURCE=1) + # Android complains about not finding -lc++_shared. + set_linker_flag("-static-libstdc++") + endif() + + set_linker_flag("-Wl,-z,relro") + set_linker_flag("-Wl,-z,now") + set_linker_flag("-Wl,-z,noexecstack") + set_compiler_flag("-fPIE") + set_linker_flag("-pie") +endif() + +if (ARCH_i686) + set_compiler_flag("-msse2") +endif() diff --git a/cmake/cross-toolchain-mingw32.cmake b/cmake/cross-toolchain-mingw32.cmake new file mode 100644 index 0000000..3c97d7a --- /dev/null +++ b/cmake/cross-toolchain-mingw32.cmake @@ -0,0 +1,16 @@ +# Target operating system and architecture +set( CMAKE_SYSTEM_NAME Windows ) +set( CMAKE_SYSTEM_PROCESSOR x86 ) + +# C/C++ compilers +set( CMAKE_C_COMPILER i686-w64-mingw32-gcc ) +set( CMAKE_CXX_COMPILER i686-w64-mingw32-g++ ) +set( CMAKE_RC_COMPILER i686-w64-mingw32-windres ) + +# Target prefix +set( CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 ) + +# Find programs using host paths and headers/libraries using target paths +set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) +set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) +set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) diff --git a/cmake/cross-toolchain-mingw64.cmake b/cmake/cross-toolchain-mingw64.cmake new file mode 100644 index 0000000..fb308a4 --- /dev/null +++ b/cmake/cross-toolchain-mingw64.cmake @@ -0,0 +1,16 @@ +# Target operating system and architecture +set( CMAKE_SYSTEM_NAME Windows ) +set( CMAKE_SYSTEM_PROCESSOR x86_64 ) + +# C/C++ compilers +set( CMAKE_C_COMPILER x86_64-w64-mingw32-gcc ) +set( CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++ ) +set( CMAKE_RC_COMPILER x86_64-w64-mingw32-windres ) + +# Target prefix +set( CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32 ) + +# Find programs using host paths and headers/libraries using target paths +set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER ) +set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) +set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) diff --git a/include-hax/fake_masm/macamd64.inc b/include-hax/fake_masm/macamd64.inc new file mode 100644 index 0000000..970487f --- /dev/null +++ b/include-hax/fake_masm/macamd64.inc @@ -0,0 +1,9 @@ +push_reg macro Reg + push Reg + .pushreg Reg + endm + +alloc_stack macro Size + sub rsp, Size + .allocstack Size + endm diff --git a/src/include/build_config.h b/src/include/build_config.h index 34a14b7..b6b9928 100644 --- a/src/include/build_config.h +++ b/src/include/build_config.h @@ -36,7 +36,7 @@ # define NACL_OSX 0 #endif -#if defined(ANDROID) +#if defined(__ANDROID__) # define NACL_ANDROID 1 #else # define NACL_ANDROID 0 diff --git a/src/include/nacl_compiler_annotations.h b/src/include/nacl_compiler_annotations.h index c9baad6..2f8a055 100644 --- a/src/include/nacl_compiler_annotations.h +++ b/src/include/nacl_compiler_annotations.h @@ -10,7 +10,7 @@ #include "native_client/src/include/build_config.h" /* MSVC supports "inline" only in C++ */ -#if NACL_WINDOWS +#if NACL_WINDOWS && defined(_MSC_VER) # define INLINE __forceinline #else # define INLINE __inline__ diff --git a/src/include/portability.h b/src/include/portability.h index d0360eb..1344148 100644 --- a/src/include/portability.h +++ b/src/include/portability.h @@ -16,6 +16,7 @@ #ifndef NATIVE_CLIENT_SRC_INCLUDE_PORTABILITY_H_ #define NATIVE_CLIENT_SRC_INCLUDE_PORTABILITY_H_ 1 +#include #include #include "native_client/src/include/build_config.h" @@ -59,7 +60,7 @@ #define GG_UINT32_C(x) (x ## U) #define GG_UINT64_C(x) GG_ULONGLONG(x) -#if NACL_WINDOWS +#if NACL_WINDOWS && defined(_MSC_VER) #define GG_LONGLONG(x) x##I64 #define GG_ULONGLONG(x) x##UI64 #else diff --git a/src/include/win/port_win.h b/src/include/win/port_win.h index 790a8fe..5dd02ed 100644 --- a/src/include/win/port_win.h +++ b/src/include/win/port_win.h @@ -74,7 +74,9 @@ typedef __int64_t int64_t; typedef __uint64_t uint64_t; typedef long off_t; +#if !defined(__MINGW32__) typedef int mode_t; +#endif typedef long _off_t; typedef long int __loff_t; typedef unsigned long DWORD; diff --git a/src/shared/gio/CMakeLists.txt b/src/shared/gio/CMakeLists.txt new file mode 100644 index 0000000..ef5fc02 --- /dev/null +++ b/src/shared/gio/CMakeLists.txt @@ -0,0 +1,6 @@ +list(APPEND GIO_INPUTS + "gio.c" + "gprintf.c" +) + +add_library(gio STATIC ${GIO_INPUTS}) diff --git a/src/shared/imc/CMakeLists.txt b/src/shared/imc/CMakeLists.txt new file mode 100644 index 0000000..4732a6d --- /dev/null +++ b/src/shared/imc/CMakeLists.txt @@ -0,0 +1,18 @@ +list(APPEND NACL_IMC_INPUTS "nacl_imc_common.cc") + +if (WIN32) + list(APPEND NACL_IMC_INPUTS + "win/nacl_imc.cc" + "win/nacl_shm.cc" + ) +else() + list(APPEND NACL_IMC_INPUTS "posix/nacl_imc_posix.cc") + + if (LINUX) + list(APPEND NACL_IMC_INPUTS "linux/nacl_imc.cc") + elseif (APPLE) + list(APPEND NACL_IMC_INPUTS "osx/nacl_imc.cc") + endif() +endif() + +add_library(imc STATIC ${NACL_IMC_INPUTS}) diff --git a/src/shared/platform/CMakeLists.txt b/src/shared/platform/CMakeLists.txt new file mode 100644 index 0000000..6f313c5 --- /dev/null +++ b/src/shared/platform/CMakeLists.txt @@ -0,0 +1,88 @@ +if (WIN32) + list(APPEND PLATFORM_INPUTS + "win/aligned_malloc.c" + "win/condition_variable.cc" + "win/lock.cc" + "win/nacl_clock.c" + "win/nacl_error.c" + "win/nacl_exit.c" + "win/nacl_fast_mutex.c" + "win/nacl_find_addrsp.c" + "win/nacl_host_desc.c" + "win/nacl_host_dir.c" + "win/lock_impl_win.cc" + "win/nacl_secure_random.c" + "win/nacl_semaphore.c" + "win/nacl_sync_win.cc" + "win/nacl_threads.c" + "win/nacl_timestamp.c" + "win/port_win.c" + "win/xlate_system_error.c" + ) + + if (MSVC) + list(APPEND PLATFORM_INPUTS "win/nacl_time.c") + else() + list(APPEND PLATFORM_INPUTS "posix/nacl_time.c") + endif() + + if (MSVC) + list(APPEND PLATFORM_FLAGS "/D_CRT_RAND_S") + list(APPEND PLATFORM_FLAGS "/D_UNICODE") + list(APPEND PLATFORM_FLAGS "/DUNICODE") + endif() +elseif (LINUX) + list(APPEND PLATFORM_INPUTS + "linux/nacl_clock.c" + "linux/nacl_host_dir.c" + "linux/nacl_semaphore.c" + ) + +#TODO: kernel_version = list(map(int, platform.release().split('.', 2)[:2])) +#TODO: if kernel_version < [3, 0]: +#TODO: cputime_test_enabled = False +elseif (APPLE) + list(APPEND PLATFORM_INPUTS + "osx/nacl_clock.c" + "osx/nacl_host_dir.c" + "osx/nacl_semaphore.c" + ) +endif() + +# It was doing: if env.Bit('posix'): +if (LINUX OR APPLE) + list(APPEND PLATFORM_INPUTS + "posix/aligned_malloc.c" + "posix/condition_variable.c" + "posix/lock.c" + "posix/nacl_error.c" + "posix/nacl_exit.c" + "posix/nacl_fast_mutex.c" + "posix/nacl_file_lock.c" # only used on Linux, but built/tested on Posix + "posix/nacl_find_addrsp.c" + "posix/nacl_host_desc.c" + "posix/nacl_secure_random.c" + "posix/nacl_thread_id.c" + "posix/nacl_threads.c" + "posix/nacl_time.c" + "posix/nacl_timestamp.c" + ) +endif() + +list(APPEND PLATFORM_INPUTS + "nacl_check.c" + "nacl_global_secure_random.c" + "nacl_host_desc_common.c" + "nacl_interruptible_condvar.c" + "nacl_interruptible_mutex.c" + "nacl_log.c" + "nacl_secure_random_common.c" + "nacl_sync_checked.c" + "nacl_time_common.c" + "platform_init.c" + "refcount_base.cc" +) + +add_library(platform STATIC ${PLATFORM_INPUTS}) +string(REPLACE ";" " " PLATFORM_FLAGS_STRING "${PLATFORM_FLAGS}") +set_target_properties(platform PROPERTIES COMPILE_FLAGS "${PLATFORM_FLAGS}") diff --git a/src/shared/platform/posix/nacl_error.c b/src/shared/platform/posix/nacl_error.c index a0d0e69..3c68b8e 100644 --- a/src/shared/platform/posix/nacl_error.c +++ b/src/shared/platform/posix/nacl_error.c @@ -10,8 +10,16 @@ #include "native_client/src/include/build_config.h" #include "native_client/src/shared/platform/nacl_error.h" +#if defined(__native_client__) + #define HAS_GNU_STRERROR_R +#elif NACL_LINUX && !NACL_ANDROID + #define HAS_GNU_STRERROR_R +#elif NACL_ANDROID && (__ANDROID_MIN_SDK_VERSION__ > 22) + #define HAS_GNU_STRERROR_R +#endif + int NaClGetLastErrorString(char* buffer, size_t length) { -#if defined(__native_client__) || (NACL_LINUX && !NACL_ANDROID) +#if defined(HAS_GNU_STRERROR_R) char* message; /* * Note some Linux distributions and newlib provide only the GNU version of diff --git a/src/shared/platform/win/lock_impl.h b/src/shared/platform/win/lock_impl.h index cb5f98b..9024ea3 100644 --- a/src/shared/platform/win/lock_impl.h +++ b/src/shared/platform/win/lock_impl.h @@ -8,7 +8,7 @@ #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_WIN_LOCK_IMPL_H_ #define NATIVE_CLIENT_SRC_TRUSTED_PLATFORM_WIN_LOCK_IMPL_H_ -#include +#include #include "native_client/src/include/nacl_macros.h" #include "native_client/src/shared/platform/nacl_sync.h" diff --git a/src/shared/platform/win/nacl_exit.c b/src/shared/platform/win/nacl_exit.c index a190175..17c7741 100644 --- a/src/shared/platform/win/nacl_exit.c +++ b/src/shared/platform/win/nacl_exit.c @@ -39,7 +39,11 @@ void NaClAbort(void) { * http://code.google.com/p/nativeclient/issues/detail?id=2772). */ while (1) { +#if defined(_MSC_VER) __halt(); +#else + __asm__("hlt"); +#endif } } diff --git a/src/shared/platform/win/port_win.c b/src/shared/platform/win/port_win.c index 2f303ff..d743bd1 100644 --- a/src/shared/platform/win/port_win.c +++ b/src/shared/platform/win/port_win.c @@ -12,7 +12,7 @@ #include "native_client/src/include/portability.h" -#if ( DO_NOT_USE_FAST_ASSEMBLER_VERSION_FOR_FFS || defined(_WIN64) ) +#if ( DO_NOT_USE_FAST_ASSEMBLER_VERSION_FOR_FFS || defined(_WIN64) || !defined(_MSC_VER) ) int ffs(int x) { int r = 1; diff --git a/src/shared/platform/win/xlate_system_error.c b/src/shared/platform/win/xlate_system_error.c index cfaca7c..b9d51f3 100644 --- a/src/shared/platform/win/xlate_system_error.c +++ b/src/shared/platform/win/xlate_system_error.c @@ -9,7 +9,7 @@ */ #include -#include +#include #include "native_client/src/shared/platform/nacl_log.h" #include "native_client/src/shared/platform/win/xlate_system_error.h" diff --git a/src/trusted/cpu_features/CMakeLists.txt b/src/trusted/cpu_features/CMakeLists.txt new file mode 100644 index 0000000..4593e0f --- /dev/null +++ b/src/trusted/cpu_features/CMakeLists.txt @@ -0,0 +1,14 @@ +if (ARCH_i686 OR ARCH_amd64) + list(APPEND CPU_FEATURES_INPUTS + "arch/x86/cpu_x86.c" + "arch/x86/cpu_xgetbv.S" + ) +elseif (ARCH_armhf OR ARCH_armel) + # For unkown reasons src/trusted/cpu_features/build.scons was building that on every architecture. + list(APPEND CPU_FEATURES_INPUTS "arch/arm/cpu_arm.c") +elseif (ARCH_mipsel) + # For unkown reasons src/trusted/cpu_features/build.scons was building that on every architecture. + list(APPEND CPU_FEATURES_INPUTS "arch/mips/cpu_mips.c") +endif() + +add_library(cpu_features STATIC ${CPU_FEATURES_INPUTS}) diff --git a/src/trusted/debug_stub/CMakeLists.txt b/src/trusted/debug_stub/CMakeLists.txt new file mode 100644 index 0000000..f1ccb70 --- /dev/null +++ b/src/trusted/debug_stub/CMakeLists.txt @@ -0,0 +1,32 @@ +list(APPEND DEBUG_INPUTS + "abi.cc" + "debug_stub.cc" + "nacl_debug.cc" + "packet.cc" + "session.cc" + "target.cc" + "thread_common.cc" + "transport_common.cc" + "transport_ipc.cc" + "util.cc" +) + +if (WIN32) + list(APPEND DEBUG_INPUTS + "win/debug_stub_win.cc" + "win/platform_impl.cc" + "win/thread_impl.cc" + ) +else() + list(APPEND DEBUG_INPUTS + "posix/debug_stub_posix.cc" + "posix/platform_impl.cc" + "posix/thread_impl.cc" + ) +endif() + +add_library(debug_stub STATIC ${DEBUG_INPUTS}) + +if (WIN32 AND NOT MSVC) + target_link_libraries(debug_stub ws2_32) +endif() diff --git a/src/trusted/desc/CMakeLists.txt b/src/trusted/desc/CMakeLists.txt new file mode 100644 index 0000000..4a0aa82 --- /dev/null +++ b/src/trusted/desc/CMakeLists.txt @@ -0,0 +1,56 @@ +add_library(nrd OBJECT "nrd_xfer.c") +list(APPEND NRD_XFER_LIBS nrd) + +if (NOT WIN32) + # Use those flags only with the nrd target. + list(APPEND NRD_FLAGS "-fno-strict-aliasing") # This was only a C flag in build.scons + list(APPEND NRD_FLAGS "-Wno-missing-field-initializers") + string(REPLACE ";" " " NRD_FLAGS_STRING "${NRD_FLAGS}") + set_target_properties(nrd PROPERTIES COMPILE_FLAGS "${NRD_FLAGS_STRING}") +endif() + +list(APPEND NRD_LIB_INPUTS + "nacl_desc_base.c" + "nacl_desc_cond.c" + "nacl_desc_custom.c" + "nacl_desc_dir.c" + "nacl_desc_effector_trusted_mem.c" + "nacl_desc_imc.c" + "nacl_desc_imc_shm.c" + "nacl_desc_invalid.c" + "nacl_desc_io.c" + "nacl_desc_mutex.c" + "nacl_desc_null.c" + "nacl_desc_quota.c" + "nacl_desc_quota_interface.c" + "nacl_desc_semaphore.c" + "nacl_desc_sync_socket.c" + "nrd_all_modules.c" +) + +if (WIN32) + list(APPEND NRD_LIB_INPUTS "win/nacl_desc.c") +else() + list(APPEND NRD_LIB_INPUTS "posix/nacl_desc.c") +endif() + +if (APPLE) + list(APPEND NRD_LIB_INPUTS "osx/nacl_desc_imc_shm_mach.c") +endif() + +if (WIN32) + list(APPEND NRD_LIB_INPUTS + "nacl_desc_conn_cap.c" + "nacl_desc_imc_bound_desc.c" + "nacl_makeboundsock.c" + ) +else() + list(APPEND NRD_LIB_INPUTS + "posix/nacl_desc_conn_cap.c" + "posix/nacl_desc_imc_bound_desc.c" + "posix/nacl_makeboundsock.c" + ) +endif() + +add_library(nrd_xfer STATIC ${NRD_LIB_INPUTS}) +target_link_libraries(nrd_xfer ${NRD_XFER_LIBS} platform nacl_base) diff --git a/src/trusted/fault_injection/CMakeLists.txt b/src/trusted/fault_injection/CMakeLists.txt new file mode 100644 index 0000000..47b4aee --- /dev/null +++ b/src/trusted/fault_injection/CMakeLists.txt @@ -0,0 +1,7 @@ +list(APPEND NACL_FI_LIB_INPUTS + "fault_injection.c" + "test_injection.c" +) + +add_library(nacl_fault_inject STATIC ${NACL_FI_LIB_INPUTS}) +target_link_libraries(nacl_fault_inject platform) diff --git a/src/trusted/interval_multiset/CMakeLists.txt b/src/trusted/interval_multiset/CMakeLists.txt new file mode 100644 index 0000000..3f9c381 --- /dev/null +++ b/src/trusted/interval_multiset/CMakeLists.txt @@ -0,0 +1,8 @@ +list(APPEND NACL_INTERVAL_LIB_INPUTS + "nacl_interval_multiset_delete.c" + "nacl_interval_multiset_factory.c" + "nacl_interval_list.c" + "nacl_interval_range_tree.c" +) + +add_library(nacl_interval ${NACL_INTERVAL_LIB_INPUTS}) diff --git a/src/trusted/nacl_base/CMakeLists.txt b/src/trusted/nacl_base/CMakeLists.txt new file mode 100644 index 0000000..39d43c9 --- /dev/null +++ b/src/trusted/nacl_base/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(nacl_base STATIC "nacl_refcount.c") +target_link_libraries(nacl_base platform) diff --git a/src/trusted/perf_counter/CMakeLists.txt b/src/trusted/perf_counter/CMakeLists.txt new file mode 100644 index 0000000..2bb69b7 --- /dev/null +++ b/src/trusted/perf_counter/CMakeLists.txt @@ -0,0 +1 @@ +add_library(nacl_perf_counter "nacl_perf_counter.c") diff --git a/src/trusted/platform_qualify/CMakeLists.txt b/src/trusted/platform_qualify/CMakeLists.txt new file mode 100644 index 0000000..09edd77 --- /dev/null +++ b/src/trusted/platform_qualify/CMakeLists.txt @@ -0,0 +1,51 @@ +if (WIN32) + list(APPEND PQL_INPUTS + "win/nacl_os_qualify.c" + "win/nacl_dep_qualify.c" + ) +elseif (LINUX OR APPLE) + list(APPEND PQL_INPUTS "posix/nacl_dep_qualify.c") + + if (LINUX) + list(APPEND PQL_INPUTS "linux/nacl_os_qualify.c") + elseif (APPLE) + list(APPEND PQL_INPUTS "osx/nacl_os_qualify.c") + endif() +endif() + +if (ARCH_i686 OR ARCH_amd64) + list(APPEND PQL_INPUTS "arch/x86/nacl_cpuallowlist.c") + + if (APPLE) + list(APPEND VCPUID_FLAGS "-mdynamic-no-pic") +# TODO: vcpuid_env.FilterOut(CCFLAGS = ['-fPIC']) + list(APPEND VCPUID_FLAGS "-fno-PIC") + elseif (LINUX) + list(APPEND VCPUID_FLAGS "-msse3") + endif() + + add_library(vcpuid OBJECT "arch/x86/vcpuid.c") + list(APPEND VCPUID_LIBS vcpuid) + + if (ARCH_i686) + list(APPEND PQL_INPUTS "arch/x86_32/nacl_dep_qualify_arch.c") + elseif (ARCH_amd64) + list(APPEND PQL_INPUTS "arch/x86_64/nacl_dep_qualify_arch.c") + endif() +elseif (ARCH_armhf OR ARCH_armel) + list(APPEND PQL_INPUTS + # Compile ARM primitives for checking XN functionality + "arch/arm/nacl_dep_qualify_arch.c" + # Compile ARM primitives for checking VFP/vector features. + "arch/arm/nacl_qualify_fpu.c" + # Compile ARM primitives for checking sandboxing features. + "arch/arm/nacl_qualify_sandbox_instrs.c" + # Compile ARM primitives for checking alignment features. + "arch/arm/nacl_qualify_unaligned.c" + ) +elseif (ARCH_mipsel) + list(APPEND PQL_INPUTS "arch/mips/nacl_qualify_fpu.c") +endif() + +add_library(platform_qual_lib STATIC ${PQL_INPUTS}) +target_link_libraries(platform_qual_lib ${VCPUID_LIBS}) diff --git a/src/trusted/platform_qualify/arch/x86/vcpuid.c b/src/trusted/platform_qualify/arch/x86/vcpuid.c index dbefa9b..cebee91 100644 --- a/src/trusted/platform_qualify/arch/x86/vcpuid.c +++ b/src/trusted/platform_qualify/arch/x86/vcpuid.c @@ -38,7 +38,7 @@ const int kMagicConst_ROUNDSS = 0xc0000000; const int kMagicConst_POPCNT = 13; const int kMagicConst_CRC32 = 0xb906c3ea; -#if !(NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64)) +#if !((NACL_WINDOWS || !defined(_MSC_VER)) && (NACL_BUILD_SUBARCH == 64)) static int asm_HasMMX(void) { volatile int before, after; before = kMagicConst; @@ -386,13 +386,13 @@ static int asm_HasCX8(void) { #endif /* 0 */ #endif /* 64-bit Windows */ -#if NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64) +#if !(NACL_WINDOWS && (NACL_BUILD_SUBARCH == 64)) || !defined(MSC_VER) static int CheckCPUFeatureDetection(NaClCPUFeaturesX86 *cpuf) { /* Unfortunately the asm_ tests will not work on 64-bit Windows */ return 0; } #else -#if (NACL_LINUX || NACL_OSX) +#if (NACL_LINUX || NACL_OSX || (NACL_WINDOWS && !defined(MSC_VER)) /* Linux/MacOS signal handling code, for trapping illegal instruction faults */ static int sawbadinstruction = 0; static struct sigaction crash_detect; diff --git a/src/trusted/service_runtime/CMakeLists.txt b/src/trusted/service_runtime/CMakeLists.txt new file mode 100644 index 0000000..5e1079e --- /dev/null +++ b/src/trusted/service_runtime/CMakeLists.txt @@ -0,0 +1,402 @@ +# Copyright (c) 2012 The Native Client Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +set(GENERATED_ROOT "${CMAKE_BINARY_DIR}/gen") +set(GENERATED "${GENERATED_ROOT}/native_client/src/trusted/service_runtime") + +# ---------------------------------------------------------- +# TODO(robertm): this library is too big and needs to be split up +# for easier unit testing +list(APPEND LDR_INPUTS + "dyn_array.c" + "elf_util.c" + "filename_util.cc" + "load_file.c" + "nacl_all_modules.c" + "nacl_app_thread.c" + "nacl_copy.c" + "nacl_desc_effector_ldr.c" + "nacl_error_gio.c" + "nacl_error_log_hook.c" + "nacl_globals.c" + "nacl_resource.c" + "nacl_signal_common.c" + "nacl_stack_safety.c" + "nacl_syscall_common.c" + "nacl_syscall_hook.c" + "nacl_syscall_list.c" + "nacl_text.c" + "nacl_valgrind_hooks.c" + "sel_addrspace.c" + "sel_ldr.c" + "sel_ldr_filename.cc" + "sel_ldr_standard.c" + "sel_main_common.c" + "sel_mem.c" + "sel_qualify.c" + "sel_validate_image.c" + "sys_clock.c" + "sys_exception.c" + "sys_fdio.c" + "sys_filename.c" + "sys_futex.c" + "sys_imc.c" + "sys_list_mappings.c" + "sys_memory.c" + "sys_parallel_io.c" + "sys_random.c" + "thread_suspension_common.c" + "thread_suspension_unwind.c" +) + +if (ARCH_i686) + list(APPEND LDR_INPUTS + "arch/x86/nacl_ldt_x86.c" + "arch/x86_32/nacl_app_32.c" + "arch/x86_32/nacl_switch_32.S" + "arch/x86_32/nacl_switch_all_regs_32.c" + "arch/x86_32/nacl_switch_all_regs_asm_32.S" + "arch/x86_32/nacl_switch_to_app_32.c" + "arch/x86_32/nacl_syscall_32.S" + "arch/x86_32/nacl_tls_32.c" + "arch/x86_32/sel_addrspace_x86_32.c" + "arch/x86_32/sel_ldr_x86_32.c" + "arch/x86_32/sel_rt_32.c" + "arch/x86_32/springboard.S" + "arch/x86_32/tramp_32.S" + ) +elseif (ARCH_amd64) + list(APPEND LDR_INPUTS + "arch/x86/nacl_ldt_x86.c" + "arch/x86_64/nacl_app_64.c" + "arch/x86_64/nacl_switch_64.S" + "arch/x86_64/nacl_switch_to_app_64.c" + "arch/x86_64/nacl_syscall_64.S" + "arch/x86_64/nacl_tls_64.c" + "arch/x86_64/sel_ldr_x86_64.c" + "arch/x86_64/sel_rt_64.c" + "arch/x86_64/tramp_64.S" + ) + + if (WIN32) + # We assemble the .asm assembly file with the Microsoft assembler + # because we need to generate x86-64 Windows unwind info, which + # the GNU assembler we use elsewhere does not support. + + list(APPEND LDR_INPUTS + "arch/x86_64/sel_addrspace_win_x86_64.c" + "arch/x86_64/fnstcw.S" + "arch/x86_64/fxsaverstor.S" + ) + + if (NOT FORCE_NO_TRUSTED_BUILD) + # This use of win64_asm_env causes an invocation of MSVC, even if sel_ldr + # would not otherwise be actually built. So don't include it if we aren't + # actually building sel_ldr + add_library(nacl_switch_unwind_win OBJECT "arch/x86_64/nacl_switch_unwind_win.asm") + list(APPEND LDR_LIBS nacl_switch_unwind_win) + endif() + else() + list(APPEND LDR_INPUTS "arch/x86_64/sel_addrspace_posix_x86_64.c") + + if (USE_AMD64_ZERO_BASED_SANDBOX) + add_definitions(-DNACL_X86_64_ZERO_BASED_SANDBOX=1) + else() + add_definitions(-DNACL_X86_64_ZERO_BASED_SANDBOX=0) + endif() + endif() +elseif (ARCH_armhf OR ARCH_armel) + list(APPEND LDR_INPUTS + "arch/arm/nacl_app.c" + "arch/arm/nacl_switch_to_app_arm.c" + "arch/arm/sel_rt.c" + "arch/arm/nacl_tls.c" + "arch/arm/sel_ldr_arm.c" + "arch/arm/sel_addrspace_arm.c" + "arch/arm/nacl_switch.S" + "arch/arm/nacl_syscall.S" + "arch/arm/tramp_arm.S" + ) +elseif (ARCH_mipsel) + list(APPEND LDR_INPUTS + "arch/mips/nacl_app.c" + "arch/mips/nacl_switch_to_app_mips.c" + "arch/mips/sel_rt.c" + "arch/mips/nacl_tls.c" + "arch/mips/sel_ldr_mips.c" + "arch/mips/sel_addrspace_mips.c" + "arch/mips/nacl_switch.S" + "arch/mips/nacl_syscall.S" + "arch/mips/tramp_mips.S" + ) +endif() + +if (WIN32) + list(APPEND LDR_INPUTS + "win/addrspace_teardown.c" + "win/nacl_ldt.c" + "win/nacl_thread_nice.c" + "win/sel_memory.c" + ) + + if (MSVC) + list(APPEND LDR_INPUTS "win/sel_segments.c") + else() + list(APPEND LDR_INPUTS "posix/x86/sel_segments.c") + endif() +elseif (APPLE) + # Rely on the c preprocessor to discover where the mach interface definitions + # are located. + set(GENERATED_NACL_EXC_C "${GENERATED}/nacl_exc.c") + set(GENERATED_NACL_EXC_H "${GENERATED}/nacl_exc.h") + set(GENERATED_NACL_EXC_SERVER_C "${GENERATED}/nacl_exc_server.c") + set(GENERATED_NACL_EXC_DEFS "${GENERATED}/exc.defs") + + file(WRITE "${GENERATED_NACL_EXC_C}" "#include ") + + # It works with clang but not with default cc (which is clang). + execute_process( + COMMAND "clang" "${CMAKE_C_COMPILER_FLAGS}" -E "${GENERATED_NACL_EXC_C}" + OUTPUT_FILE "${GENERATED_NACL_EXC_DEFS}" + ) + + include_directories("${GENERATED_ROOT}") + + execute_process( + COMMAND "${PYTHON}" + "${CMAKE_CURRENT_LIST_DIR}/osx/run_mig.py" + "${GENERATED_NACL_EXC_DEFS}" + "${GENERATED_NACL_EXC_H}" + "${GENERATED_NACL_EXC_SERVER_C}" + ) + + list(APPEND LDR_INPUTS + "${GENERATED_NACL_EXC_SERVER_C}" + "osx/crash_filter.c" + "osx/mach_exception_handler.c" + "osx/mach_thread_map.c" + "osx/nacl_ldt.c" + "osx/nacl_thread_nice.c" + "posix/addrspace_teardown.c" + "posix/sel_memory.c" + "posix/x86/sel_segments.c" + ) +elseif (LINUX) + list(APPEND LDR_INPUTS + "linux/nacl_bootstrap_args.c" + "linux/nacl_thread_nice.c" + "linux/r_debug.c" + "linux/reserved_at_zero.c" + "posix/addrspace_teardown.c" + "posix/sel_memory.c" + ) + + if (ARCH_i686 OR ARCH_amd64) + list(APPEND LDR_INPUTS + "linux/x86/nacl_ldt.c" + "posix/x86/sel_segments.c" + ) + elseif (ARCH_armhf OR ARCH_armel) + list(APPEND LDR_INPUTS "linux/arm/sel_segments.c") + elseif (ARCH_mipsel) + list(APPEND LDR_INPUTS "linux/mips/sel_segments.c") + endif() +endif() + +# ------------------------------------------------------------- +# Add OS and architecture specific signal handling files. +# +if (WIN32) + list(APPEND LDR_INPUTS + "win/debug_exception_handler.c" + "win/debug_exception_handler_standalone.c" + "win/nacl_signal_stack.c" + "win/thread_handle_map.c" + "win/thread_suspension.c" + "win/sel_addrspace_win.c" + ) + + if (ARCH_i686) + list(APPEND LDR_INPUTS "win/nacl_signal_32.c") + elseif (ARCH_amd64) + list(APPEND LDR_INPUTS + "win/exception_patch/exit_fast.S" + "win/exception_patch/intercept.S" + "win/exception_patch/ntdll_patch.c" + "win/nacl_signal_64.c" + ) + else() + message(FATAL_ERROR "Unsupported target") + endif() +endif() + +if (LINUX) + list(APPEND LDR_INPUTS + "linux/thread_suspension.c" + "posix/nacl_signal_stack.c" + "posix/sel_addrspace_posix.c" + ) + + if (ARCH_armhf OR ARCH_armel) + list(APPEND LDR_INPUTS "linux/nacl_signal_arm.c") + elseif (ARCH_mipsel) + list(APPEND LDR_INPUTS "linux/nacl_signal_mips.c") + elseif (ARCH_i686) + list(APPEND LDR_INPUTS "linux/nacl_signal_32.c") + elseif (ARCH_amd64) + list(APPEND LDR_INPUTS "linux/nacl_signal_64.c") + else() + message(FATAL_ERROR "Unsupported target") + endif() + + add_library(nacl_signal STATIC "linux/nacl_signal.c") + list(APPEND LDR_LIBS nacl_signal) +#TODO: nacl_signal_env = env.Clone() + if (ARCH_i686) + # nacl_signal.c needs to be compiled without the stack protector + # on i386. + # See https://code.google.com/p/nativeclient/issues/detail?id=3581. +#TODO: nacl_signal_env.FilterOut(CCFLAGS=['-fstack-protector', '-fstack-protector-all']) + set_target_properties(nacl_signal PROPERTIES COMPILE_FLAGS "-fno-stack-protector") + endif() +endif() + +if (APPLE) + list(APPEND LDR_INPUTS + "osx/thread_suspension.c" + "posix/nacl_signal_stack.c" + "posix/sel_addrspace_posix.c" + ) + + if (ARCH_i686) + list(APPEND LDR_INPUTS "osx/nacl_signal_32.c") + elseif (ARCH_amd64) + list(APPEND LDR_INPUTS "osx/nacl_signal_64.c") + else() + message(FATAL_ERROR "Unsupported target") + endif() +endif() + +if (WIN32) + list(APPEND LDR_INPUTS "win/vm_hole.c") +else() + list(APPEND LDR_INPUTS "generic/vm_hole.c") +endif() + +#TODO: syscall_gen_flags = '-a ${ARCHITECTURE} -s ${TARGET_SUBARCH}' + +#TODO: env.Append(SYSCALL_GEN_FLAGS=syscall_gen_flags) + +add_library(sel OBJECT ${LDR_INPUTS}) +list(APPEND LDR_LIBS sel) + +add_library(sel_main OBJECT "sel_main.c") +list(APPEND LDR_LIBS sel_main) + +# add_library(sel_main_chrome OBJECT "sel_main_chrome.c") + +add_library(env_cleanser OBJECT "env_cleanser.c") +list(APPEND LDR_LIBS env_cleanser) + +add_library(nacl_error_code OBJECT "nacl_error_code.c") +list(APPEND LDR_LIBS nacl_error_code) + +list(APPEND LDR_LIBS debug_stub) # not listed in src/trusted/service_runtime/build.scons +list(APPEND LDR_LIBS nrd_xfer) +list(APPEND LDR_LIBS nacl_perf_counter) +list(APPEND LDR_LIBS nacl_base) +list(APPEND LDR_LIBS imc) +list(APPEND LDR_LIBS nacl_fault_inject) +list(APPEND LDR_LIBS nacl_interval) +list(APPEND LDR_LIBS platform) +list(APPEND LDR_LIBS gio) # not listed in src/trusted/service_runtime/build.scons +list(APPEND LDR_LIBS platform_qual_lib) +list(APPEND LDR_LIBS validators) + +if (ARCH_i686 OR ARCH_amd64) + list(APPEND LDR_LIBS dfa_validate_caller) +elseif (ARCH_armhf OR ARCH_armel) + list(APPEND LDR_LIBS ncvalidate_arm_v2) + list(APPEND LDR_LIBS arm_validator_reporters) +elseif (ARCH_mipsel) + list(APPEND LDR_LIBS ncvalidate_mips) +endif() + +if (ARCH_i686 OR ARCH_amd64) + list(APPEND LDR_LIBS nccopy) # not listed in src/trusted/service_runtime/build.scons +endif() + +list(APPEND LDR_LIBS cpu_features) # not listed in src/trusted/service_runtime/build.scons + +if (WIN32) + set(MMAP_TEST_CHECK_CC "win/mmap_test_check.cc") +elseif (APPLE) + set(MMAP_TEST_CHECK_CC "osx/mmap_test_check.cc") +elseif (LINUX) + set(MMAP_TEST_CHECK_CC "linux/mmap_test_check.cc") +else() + message(FATAL_ERROR "Unsupported host OS") +endif() + +add_library(sel_test "${MMAP_TEST_CHECK_CC}") +list(APPEND LDR_LIBS sel_test) + +# NOTE(robertm): these extra libs were orignially only added to the +# sel_ldr binary +# TODO(robertm): see who really needs them and remove +if (WIN32) +# FIXME: Unused for now. + set(LIBS + ws2_32 + kernel32 + advapi32 + winmm + # TODO(gregoryd): ntdll.lib is required for sem_get_value implementation but + # it is available in Windows DDK only. The DDK is not + # in third_party, but we might need to add it if we want to use it. + # ntdll + ) +endif() + +if (NOT COVERAGE_ENABLED OR NOT WIN32) +#TODO: sel_main_objs = [env.ComponentObject('nacl_test_injection_main.c')] + add_library(nacl_test_injection_main OBJECT "nacl_test_injection_main.c") + list(APPEND LDR_LIBS nacl_test_injection_main) + + if (LINUX) + # FIXME: librt was added by src/shared/imc/build.scons for Linux but not Android. + # FIXME: libdl was added by (root)/SConstruct for Linux on armhf and Android on armel. + # get_plugin_dirname.cc has a dependency on dladdr + list(APPEND LDR_LIBS "-ldl") + list(APPEND LDR_LIBS "-lrt") + list(APPEND LDR_LIBS "-pthread") + endif() + + add_executable(sel_ldr) + target_link_libraries(sel_ldr ${LDR_LIBS}) + + if (APPLE) + # This target exists only to check that the service_runtime code + # can successfully be linked into a Mac OS X dynamic library. Our + # assembly code needs to be PIC-friendly and linkable in this + # context, because it is linked into a dynamic library inside + # Chromium, and OS X is strict about TEXTRELs. Without this, the + # standalone build won't catch some mistakes that can break the + # Chromium build. Linking a dylib here works because -fPIC is the + # default for all C code on OS X. +#TODO: dylib_env = env.Clone() +#TODO: dylib_env.Append(LINKFLAGS=['-bundle']) +#TODO: dylib_env.ComponentProgram('dummy_sel_ldr.dylib', sel_main_objs, EXTRA_LIBS=['sel_main']) + endif() + + # NOTE: we do not have segments on ARM +endif() + +if (LINUX AND ARCH_amd64) +#TODO: sel_ldr_seccomp_node = env.ComponentProgram('sel_ldr_seccomp', +#TODO: ['sel_ldr_seccomp_main.c'], +#TODO: EXTRA_LIBS=['sel_main', +#TODO: 'seccomp_bpf']) +#TODO: env.SDKInstallBin('sel_ldr_seccomp', sel_ldr_seccomp_node) +endif() diff --git a/src/trusted/service_runtime/arch/x86_32/sel_rt_32.c b/src/trusted/service_runtime/arch/x86_32/sel_rt_32.c index 5757b6c..364aaad 100644 --- a/src/trusted/service_runtime/arch/x86_32/sel_rt_32.c +++ b/src/trusted/service_runtime/arch/x86_32/sel_rt_32.c @@ -90,7 +90,7 @@ int NaClAppThreadInitArchSpecific(struct NaClAppThread *natp, * Save the system's state of the x87 FPU control word so we can restore * the same state when returning to trusted code. */ -#if NACL_WINDOWS +#if NACL_WINDOWS && defined(_MSC_VER) { uint16_t sys_fcw; __asm { diff --git a/src/trusted/service_runtime/arch/x86_64/nacl_switch_unwind_win.asm b/src/trusted/service_runtime/arch/x86_64/nacl_switch_unwind_win.asm index d5dd93a..6ead094 100644 --- a/src/trusted/service_runtime/arch/x86_64/nacl_switch_unwind_win.asm +++ b/src/trusted/service_runtime/arch/x86_64/nacl_switch_unwind_win.asm @@ -2,7 +2,7 @@ ; Use of this source code is governed by a BSD-style license that can be ; found in the LICENSE file. -include ksamd64.inc +include macamd64.inc EXTERN NaClSwitch : QWORD diff --git a/src/trusted/service_runtime/linux/CMakeLists.txt b/src/trusted/service_runtime/linux/CMakeLists.txt new file mode 100644 index 0000000..6f8885c --- /dev/null +++ b/src/trusted/service_runtime/linux/CMakeLists.txt @@ -0,0 +1,131 @@ +#TODO: bootstrap_env = env.Clone() +#TODO: bootstrap_env.Replace(CLANG_OPTS='') +#TODO: bootstrap_env.FilterOut(CCFLAGS=['-fstack-protector', '-fPIC', '-fPIE', '-pedantic', '$COVERAGE_CCFLAGS'], +list(APPEND BOOTSTRAP_FLAGS "-fno-pic") +list(APPEND BOOTSTRAP_FLAGS "-fno-PIC") +list(APPEND BOOTSTRAP_FLAGS "-fno-pie") +# Assumed to be what is expected, as -fno-pie was passed twice in src/trusted/service_runtime/build.scons. +list(APPEND BOOTSTRAP_FLAGS "-fno-PIE") +list(APPEND BOOTSTRAP_FLAGS "-fno-stack-protector") +# Was only a C flag in src/trusted/service_runtime/build.scons. +list(APPEND BOOTSTRAP_FLAGS "-Wdeclaration-after-statement") + +if (ANDROID) + # It is is known to break the Android build, making bits/fortify/unistd.h + # unable to find SSIZE_MAX (this may be an NDK bug). + remove_definitions(-D_FORTIFY_SOURCE=2) +endif() + +# Using optimizations when building with GCC breaks the program on armhf. +if (NOT DAEMON_CXX_COMPILER_Clang_COMPATIBILITY) + list(APPEND BOOTSTRAP_FLAGS "-O0") +endif() + +# The src/trusted/service_runtime/build.scons file was only setting them on +# Clang but GCC accepts them as well. +if (ON) # DAEMON_CXX_COMPILER_Clang_COMPATIBILITY) + list(APPEND BOOTSTRAP_FLAGS "-ffreestanding") + # TODO(bbudge) Remove -Qunused-arguments when Clang supports -fno-pic. + # list(APPEND BOOTSTRAP_FLAGS "-Qunused-arguments") + list(APPEND BOOTSTRAP_FLAGS "-Wno-builtin-macro-redefined") + + # FIXME: It doesn't work; CMake puts it in flags that is passed after the + # definitions and then it unsets it after overwriting it, not before. + # add_definitions("-U__STDC_HOSTED__") + + add_definitions("-D__STDC_HOSTED__=1") +endif() + +set(COMPILER_OVERRIDE "${CMAKE_CXX_COMPILER}") + +if (ARCH_amd64) + set(LD_EMUL "elf_x86_64") + + if (USE_AMD64_ZERO_BASED_SANDBOX) + # For the zero-based 64-bit sandbox, we want to reserve 44GB of address + # space: 4GB for the program plus 40GB of guard pages. Due to a binutils + # bug (see http://sourceware.org/bugzilla/show_bug.cgi?id=13400), the + # amount of address space that the linker can pre-reserve is capped + # at 4GB. For proper reservation, GNU ld version 2.22 or higher + # needs to be used. + # + # Without the bug fix, trying to reserve 44GB will result in + # pre-reserving the entire capped space of 4GB. This tricks the run-time + # into thinking that we can mmap up to 44GB. This is unsafe as it can + # overwrite the run-time program itself and/or other programs. Because + # of this, we only reserve 4GB. + # + # TODO(arbenson): remove these comments and reserve 44GB once the + # necessary ld version becomes standard. + set(RESERVE_TOP "0x100000000") + # The reserve_top value gets interpreted as a pointer in + # linux/nacl_bootstrap.c. By default, mcmodel is set to small, + # which restricts code and data to the first 2GB. With + # mcmodel set to small or medium, the reserve_top value is + # truncated, which produces an error. With mcmodel set to large, + # there is no restriction on the code and data, so we can + # safely set reserve_top to 0x100000000. + list(APPEND BOOTSTRAP_FLAGS "-mcmodel=large") + else() + set(RESERVE_TOP "0x0") + endif() +elseif (ARCH_i686) + set(LD_EMUL "elf_i386") + set(RESERVE_TOP "0x40000000") +elseif (ARCH_armhf OR ARCH_armel) + set(LD_EMUL "armelf_linux_eabi") + set(RESERVE_TOP "0x40002000") + + if (DAEMON_CXX_COMPILER_Clang_COMPATIBILITY) + if (ANDROID) + if (ARCH_armel) + set(COMPILER_OVERRIDE "arm-linux-androideabi-g++") + endif() + elseif (LINUX) + if (ARCH_armhf) + set(COMPILER_OVERRIDE "arm-linux-gnueabihf-g++") + elseif (ARCH_armel) + set(COMPILER_OVERRIDE "arm-linux-gnueabi-g++") + endif() + endif() + endif() +elseif (ARCH_mipsel) + set(LD_EMUL "elf32ltsmip") + set(RESERVE_TOP "0x40008000") +endif() + +string(REPLACE ";" " " BOOTSTRAP_FLAGS_STRING "${BOOTSTRAP_FLAGS}") + +add_library(nacl_bootstrap OBJECT "nacl_bootstrap.c") +set_target_properties(nacl_bootstrap PROPERTIES COMPILE_FLAGS ${BOOTSTRAP_FLAGS_STRING}) + +if (USE_ARMHF_16K_PAGESIZE) + set(MAX_PAGE_SIZE 0x4000) +else() + set(MAX_PAGE_SIZE 0x1000) +endif() + +add_custom_target(nacl_bootstrap_raw + COMMAND env "${PYTHON}" + "${CMAKE_CURRENT_LIST_DIR}/ld_bfd.py" + --compiler "${COMPILER_OVERRIDE}" + -m "${LD_EMUL}" + --build-id + -static + -z "max-page-size=${MAX_PAGE_SIZE}" + --defsym RESERVE_TOP="${RESERVE_TOP}" + --script "${CMAKE_CURRENT_LIST_DIR}/nacl_bootstrap.x" + -o "${CMAKE_CURRENT_BINARY_DIR}/nacl_bootstrap_raw" + "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/nacl_bootstrap.dir/nacl_bootstrap.c.o" + DEPENDS nacl_bootstrap + BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/nacl_bootstrap.dir/nacl_bootstrap.c.o" +) + +add_custom_target(nacl_helper_bootstrap ALL + COMMAND "${PYTHON}" + "${CMAKE_CURRENT_LIST_DIR}/nacl_bootstrap_munge_phdr.py" + "${CMAKE_BINARY_DIR}/src/trusted/service_runtime/linux/nacl_bootstrap_raw" + "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nacl_helper_bootstrap" + DEPENDS nacl_bootstrap_raw + BYPRODUCTS "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nacl_helper_bootstrap" +) diff --git a/src/trusted/service_runtime/linux/nacl_bootstrap.c b/src/trusted/service_runtime/linux/nacl_bootstrap.c index 4cf204c..0cd37fc 100644 --- a/src/trusted/service_runtime/linux/nacl_bootstrap.c +++ b/src/trusted/service_runtime/linux/nacl_bootstrap.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -290,8 +291,8 @@ static ElfW(Addr) load_elf_file(const char *filename, fail(filename, "ELF file has unreasonable ", "e_phnum", ehdr.e_phnum, NULL, 0); - if (ehdr.e_type != ET_DYN) - fail(filename, "ELF file not ET_DYN! ", + if (ehdr.e_type != ET_DYN && ehdr.e_type != ET_EXEC) + fail(filename, "ELF file not ET_DYN neither ET_EXEC! ", "e_type", ehdr.e_type, NULL, 0); my_pread(filename, "Failed to read program headers from ELF file! ", diff --git a/src/trusted/service_runtime/nacl_signal.h b/src/trusted/service_runtime/nacl_signal.h index e3a8fa1..2301ed4 100644 --- a/src/trusted/service_runtime/nacl_signal.h +++ b/src/trusted/service_runtime/nacl_signal.h @@ -58,7 +58,7 @@ struct NaClExceptionFrame; #define NACL_ABI_WIFSIGNALED(status) ((((status) + 1) & 0x7f) > 1) #define NACL_ABI_W_EXITCODE(ret, sig) ((((ret) & 0xff) << 8) + ((sig) & 0x7f)) -#if NACL_WINDOWS +#if NACL_WINDOWS && defined(_MSC_VER) enum PosixSignals { SIGINT = 2, SIGQUIT = 3, diff --git a/src/trusted/service_runtime/sel_ldr.c b/src/trusted/service_runtime/sel_ldr.c index 4dbc761..7bcf97c 100644 --- a/src/trusted/service_runtime/sel_ldr.c +++ b/src/trusted/service_runtime/sel_ldr.c @@ -912,7 +912,7 @@ void NaClVmIoPendingCheck_mu(struct NaClApp *nap, * We need its symbol in the symbol table so don't inline it. * TODO(dje): add some explanation for the non-GDB person. */ -#if NACL_WINDOWS +#if NACL_WINDOWS && defined(_MSVC_VER) __declspec(dllexport noinline) #endif #ifdef __GNUC__ diff --git a/src/trusted/validator/CMakeLists.txt b/src/trusted/validator/CMakeLists.txt new file mode 100644 index 0000000..8ab5f82 --- /dev/null +++ b/src/trusted/validator/CMakeLists.txt @@ -0,0 +1,7 @@ +# set(NCFILEUTILS "ncfileutils${ARCH_SUFFIX}") +# add_library(${NCFILEUTILS} OBJECT "ncfileutil.c") + +add_library(validation_cache OBJECT "validation_cache.c") + +add_library(validators STATIC "validator_init.c") +target_link_libraries(validators validation_cache) diff --git a/src/trusted/validator/validation_cache.c b/src/trusted/validator/validation_cache.c index b9d9536..f8ce53e 100644 --- a/src/trusted/validator/validation_cache.c +++ b/src/trusted/validator/validation_cache.c @@ -21,7 +21,7 @@ #include "native_client/src/trusted/validator/validation_metadata.h" #if NACL_WINDOWS -#include +#include #include #endif diff --git a/src/trusted/validator_arm/CMakeLists.txt b/src/trusted/validator_arm/CMakeLists.txt new file mode 100644 index 0000000..1121dd9 --- /dev/null +++ b/src/trusted/validator_arm/CMakeLists.txt @@ -0,0 +1,98 @@ +# Android compiler cannot compile NDK C++ headers with these. + +if (LINUX AND NOT ANDROID) + # TODO(cbiffle): give everyone else these warnings too. + # TODO(karl): Why does -fno-rtti cause linking issues. + # CXXFLAGS='-Weffc++ -Woverloaded-virtual -fno-rtti -fomit-frame-pointer', + list(APPEND VALIDATOR_FLAGS -Weffc) + list(APPEND VALIDATOR_FLAGS -Woverloaded-virtual) + list(APPEND VALIDATOR_FLAGS -fomit-frame-pointer) +endif() + +list(APPEND GEN_TEST_LIST + # Generated table file names. + "gen/arm32_decode_advanced_simd_data_processing_instructions_tests.cc" + "gen/arm32_decode_advanced_simd_element_or_structure_load_store_instructions_tests.cc" + "gen/arm32_decode_ARMv7_tests.cc" + "gen/arm32_decode_branch_branch_with_link_and_block_data_transfer_tests.cc" + "gen/arm32_decode_coprocessor_instructions_and_supervisor_call_tests.cc" + "gen/arm32_decode_data_processing_and_miscellaneous_instructions_tests.cc" + "gen/arm32_decode_data_processing_immediate_tests.cc" + "gen/arm32_decode_data_processing_register_shifted_register_tests.cc" + "gen/arm32_decode_data_processing_register_tests.cc" + "gen/arm32_decode_extension_register_load_store_instructions_tests.cc" + "gen/arm32_decode_extra_load_store_instructions_tests.cc" + "gen/arm32_decode_floating_point_data_processing_instructions_tests.cc" + "gen/arm32_decode_halfword_multiply_and_multiply_accumulate_tests.cc" + "gen/arm32_decode_load_store_word_and_unsigned_byte_tests.cc" + "gen/arm32_decode_media_instructions_tests.cc" + "gen/arm32_decode_memory_hints_advanced_simd_instructions_and_miscellaneous_instructions_tests.cc" + "gen/arm32_decode_miscellaneous_instructions_tests.cc" + "gen/arm32_decode_msr_immediate_and_hints_tests.cc" + "gen/arm32_decode_multiply_and_multiply_accumulate_tests.cc" + "gen/arm32_decode_other_floating_point_data_processing_instructions_tests.cc" + "gen/arm32_decode_packing_unpacking_saturation_and_reversal_tests.cc" + "gen/arm32_decode_parallel_addition_and_subtraction_signed_tests.cc" + "gen/arm32_decode_parallel_addition_and_subtraction_unsigned_tests.cc" + "gen/arm32_decode_saturating_addition_and_subtraction_tests.cc" + "gen/arm32_decode_signed_multiply_signed_and_unsigned_divide_tests.cc" + "gen/arm32_decode_simd_dp_1imm_tests.cc" + "gen/arm32_decode_simd_dp_2misc_tests.cc" + "gen/arm32_decode_simd_dp_2scalar_tests.cc" + "gen/arm32_decode_simd_dp_2shift_tests.cc" + "gen/arm32_decode_simd_dp_3diff_tests.cc" + "gen/arm32_decode_simd_dp_3same_tests.cc" + "gen/arm32_decode_synchronization_primitives_tests.cc" + "gen/arm32_decode_transfer_between_arm_core_and_extension_register_8_16_and_32_bit_tests.cc" + "gen/arm32_decode_transfer_between_arm_core_and_extension_registers_64_bit_tests.cc" + "gen/arm32_decode_unconditional_instructions_tests.cc" +) + +list(APPEND GEN_ACTUAL_LIST + "gen/arm32_decode_actuals_1.cc" + "gen/arm32_decode_actuals_1.h" + "gen/arm32_decode_actuals_2.cc" + "gen/arm32_decode_actuals_2.h" +) + +list(APPEND GEN_BASELINE_LIST + "gen/arm32_decode_baselines_1.cc" + "gen/arm32_decode_baselines_1.h" + "gen/arm32_decode_baselines_2.cc" + "gen/arm32_decode_baselines_2.h" + "gen/arm32_decode_baselines_3.cc" + "gen/arm32_decode_baselines_3.h" +) + +list(APPEND GEN_OTHER_LIST + "gen/arm32_decode.cc" + "gen/arm32_decode.h" + "gen/arm32_decode_actuals.h" + "gen/arm32_decode_baselines.h" +# "gen/arm32_decode_named.cc" # Why? + "gen/arm32_decode_named_classes.h" + "gen/arm32_decode_named_bases.h" + "gen/arm32_decode_named_decoder.h" + ${GEN_ACTUAL_LIST} + ${GEN_BASELINE_LIST} +) + +list(APPEND VALIDATOR_INPUTS + "address_set.cc" + "inst_classes.cc" + "model.cc" + "arm_helpers.cc" + "validator.cc" +) + +string(REPLACE ";" " " VALIDATOR_FLAGS_STRING "${VALIDATOR_FLAGS}") + +add_library(arm_validator_core OBJECT ${VALIDATOR_INPUTS} ${GEN_OTHER_LIST}) +set_target_properties(arm_validator_core PROPERTIES FLAGS "${VALIDATOR_FLAGS_STRING}") + +add_library(ncvalidate_arm_v2 STATIC "ncvalidate.cc") +target_link_libraries(ncvalidate_arm_v2 arm_validator_core) # We don't support OPTIONAL_COVERAGE_LIBS. +set_target_properties(ncvalidate_arm_v2 PROPERTIES FLAGS "${VALIDATOR_FLAGS_STRING}") + +add_library(arm_validator_reporters STATIC "problem_reporter.cc") +set_target_properties(arm_validator_reporters PROPERTIES FLAGS "${VALIDATOR_FLAGS_STRING}") diff --git a/src/trusted/validator_mips/CMakeLists.txt b/src/trusted/validator_mips/CMakeLists.txt new file mode 100644 index 0000000..7a748dc --- /dev/null +++ b/src/trusted/validator_mips/CMakeLists.txt @@ -0,0 +1,21 @@ +if (LINUX AND NOT ANDROID) + list(APPEND VALIDATOR_FLAGS -Weffc) + list(APPEND VALIDATOR_FLAGS -Woverloaded-virtual) + list(APPEND VALIDATOR_FLAGS -fno-rtti) + list(APPEND VALIDATOR_FLAGS -fomit-frame-pointer) +endif() + +list(APPEND VALIDATOR_INPUTS + "address_set.cc" + "validator.cc" + "gen/decode.cc" +) + +string(REPLACE ";" " " VALIDATOR_FLAGS_STRING "${VALIDATOR_FLAGS}") + +add_library(mips_validator_core OBJECT ${VALIDATOR_INPUTS}) +set_target_properties(mips_validator_core PROPERTIES FLAGS "${VALIDATOR_FLAGS_STRING}") + +add_library(ncvalidate_mips STATIC "ncvalidate.cc") +target_link_libraries(ncvalidate_mips mips_validator_core) # We don't support OPTIONAL_COVERAGE_LIBS. +set_target_properties(ncvalidate_mips PROPERTIES FLAGS "${VALIDATOR_FLAGS_STRING}") diff --git a/src/trusted/validator_ragel/CMakeLists.txt b/src/trusted/validator_ragel/CMakeLists.txt new file mode 100644 index 0000000..050d9df --- /dev/null +++ b/src/trusted/validator_ragel/CMakeLists.txt @@ -0,0 +1,34 @@ +add_definitions("-DVALIDATOR_EXPORT=DLLEXPORT") + +# src/trusted/validator_ragel/build.scons built both for both bitness +# because it was needed for the rdfa_validator library which looks to +# only be used for running some benchmark. +if (ARCH_i686) + set(VALIDATOR_LIB validator32) + add_library(${VALIDATOR_LIB} OBJECT "gen/validator_x86_32.c") +elseif (ARCH_amd64) + set(VALIDATOR_LIB validator64) + add_library(${VALIDATOR_LIB} OBJECT "gen/validator_x86_64.c") +endif() + +add_library(validator_features_all OBJECT "validator_features_all.c") +list(APPEND FEATURES_LIBS validator_features_all) +add_library(validator_features_validator OBJECT "validator_features_validator.c") +list(APPEND FEATURES_LIBS validator_features_validator) + +if (ARCH_i686) + set(DFA_VALIDATE_CALLER_INPUTS + "dfa_validate_32.c" + "dfa_validate_common.c" + ) +elseif (ARCH_amd64) + set(DFA_VALIDATE_CALLER_INPUTS + "dfa_validate_64.c" + "dfa_validate_common.c" + ) +endif() + +add_library(dfa_validate_caller${ARCH_SUFFIX} STATIC ${DFA_VALIDATE_CALLER_INPUTS}) +target_link_libraries(dfa_validate_caller${ARCH_SUFFIX} ${FEATURES_LIBS} ${VALIDATOR_LIB}) + +add_library(dfa_validate_caller ALIAS dfa_validate_caller${ARCH_SUFFIX}) diff --git a/src/trusted/validator_ragel/bitmap.h b/src/trusted/validator_ragel/bitmap.h index dec2a0d..b39523c 100644 --- a/src/trusted/validator_ragel/bitmap.h +++ b/src/trusted/validator_ragel/bitmap.h @@ -15,7 +15,7 @@ #include "native_client/src/include/nacl_macros.h" #include "native_client/src/include/portability.h" -#if NACL_WINDOWS +#if NACL_WINDOWS && defined(_MSC_VER) # define FORCEINLINE __forceinline #else # define FORCEINLINE __inline __attribute__ ((always_inline)) diff --git a/src/trusted/validator_ragel/decoding.h b/src/trusted/validator_ragel/decoding.h index 64087b7..4554124 100644 --- a/src/trusted/validator_ragel/decoding.h +++ b/src/trusted/validator_ragel/decoding.h @@ -19,7 +19,7 @@ #include "native_client/src/include/build_config.h" #include "native_client/src/trusted/validator_ragel/decoder.h" -#if NACL_WINDOWS +#if NACL_WINDOWS && defined(_MSC_VER) # define FORCEINLINE __forceinline #else # define FORCEINLINE __inline __attribute__ ((always_inline)) diff --git a/src/trusted/validator_x86/CMakeLists.txt b/src/trusted/validator_x86/CMakeLists.txt new file mode 100644 index 0000000..add7628 --- /dev/null +++ b/src/trusted/validator_x86/CMakeLists.txt @@ -0,0 +1,6 @@ +list(APPEND NCCOPY_INPUTS + "nccopycode.c" + "nccopycode_stores.S" +) + +add_library(nccopy STATIC ${NCCOPY_INPUTS})