diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8a2d47c --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,131 @@ +name: "Build" +on: [push, pull_request] + +defaults: + run: + shell: bash + +jobs: + source-check: + name: "Source Check" + runs-on: ubuntu-latest + + steps: + - name: "Checkout" + uses: actions/checkout@v2 + + - name: "Setup node.js" + uses: actions/setup-node@v1 + with: + node-version: "14" + + - name: "Check Enumerations" + run: | + cd tools + node enumgen.js --verify + + build: + strategy: + fail-fast: false + matrix: + include: + - { title: "diag-asan" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release", diagnose: "address" } + - { title: "diag-ubsan" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release", diagnose: "undefined" } + - { title: "diag-valgrind" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release", diagnose: "valgrind" } + + - { title: "no-deprecated" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release", add_defs: ",ASMJIT_NO_DEPRECATED=1" } + - { title: "no-intrinsics" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release", add_defs: ",ASMJIT_NO_INTRINSICS=1" } + - { title: "no-logging" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release", add_defs: ",ASMJIT_NO_LOGGING=1" } + - { title: "no-builder" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release", add_defs: ",ASMJIT_NO_BUILDER=1" } + - { title: "no-compiler" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release", add_defs: ",ASMJIT_NO_COMPILER=1" } + + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc" , architecture: "x86", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc" , architecture: "x64", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-4.8" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-4.8" , architecture: "x86", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-4.8" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-4.8" , architecture: "x64", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-5" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-5" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-6" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-6" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-7" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-7" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-8" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-8" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-9" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-9" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-10" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-10" , architecture: "x86", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-10" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "gcc-10" , architecture: "x64", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x86", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang" , architecture: "x64", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang-9" , architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang-9" , architecture: "x86", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang-9" , architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang-9" , architecture: "x64", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang-10", architecture: "x86", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang-10", architecture: "x86", build_type: "Release" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang-10", architecture: "x64", build_type: "Debug" } + - { title: "linux" , os: "ubuntu-latest" , cxx: "clang-10", architecture: "x64", build_type: "Release" } + + - { title: "osx-10.15" , os: "macos-10.15" , cxx: "gcc-9" , architecture: "x64", build_type: "Debug" } + - { title: "osx-10.15" , os: "macos-10.15" , cxx: "gcc-9" , architecture: "x64", build_type: "Release" } + - { title: "osx-10.15" , os: "macos-10.15" , cxx: "clang" , architecture: "x64", build_type: "Debug" } + - { title: "osx-10.15" , os: "macos-10.15" , cxx: "clang" , architecture: "x64", build_type: "Release" } + - { title: "osx-11.0" , os: "macos-11.0" , cxx: "gcc-9" , architecture: "x64", build_type: "Debug" } + - { title: "osx-11.0" , os: "macos-11.0" , cxx: "gcc-9" , architecture: "x64", build_type: "Release" } + - { title: "osx-11.0" , os: "macos-11.0" , cxx: "clang" , architecture: "x64", build_type: "Debug" } + - { title: "osx-11.0" , os: "macos-11.0" , cxx: "clang" , architecture: "x64", build_type: "Release" +} + - { title: "windows" , os: "windows-latest", cxx: "vs2019" , architecture: "x86", build_type: "Debug" } + - { title: "windows" , os: "windows-latest", cxx: "vs2019" , architecture: "x86", build_type: "Release" } + - { title: "windows" , os: "windows-latest", cxx: "vs2019" , architecture: "x64", build_type: "Debug" } + - { title: "windows" , os: "windows-latest", cxx: "vs2019" , architecture: "x64", build_type: "Release" } + + name: "${{matrix.title}} (${{matrix.cxx}}, ${{matrix.architecture}}, ${{matrix.build_type}})" + runs-on: "${{matrix.os}}" + + steps: + - name: "Checkout" + uses: actions/checkout@v2 + + - name: "Python" + uses: actions/setup-python@v2 + with: + python-version: "3.x" + + - name: "Prepare" + run: python -B .github/workflows/run-step.py + --step=prepare + --compiler=${{matrix.cxx}} + --architecture=${{matrix.architecture}} + --diagnose=${{matrix.diagnose}} + + - name: "Configure" + run: python -B .github/workflows/run-step.py + --step=configure + --compiler=${{matrix.cxx}} + --architecture=${{matrix.architecture}} + --build-type=${{matrix.build_type}} + --build-defs=ASMJIT_TEST=ON${{matrix.add_defs}} + --diagnose=${{matrix.diagnose}} + + - name: "Build" + run: python -B .github/workflows/run-step.py + --step=build + --compiler=${{matrix.cxx}} + --architecture=${{matrix.architecture}} + --build-type=${{matrix.build_type}} + --diagnose=${{matrix.diagnose}} + + - name: "Test" + run: python -B .github/workflows/run-step.py + --step=test + --build-type=${{matrix.build_type}} + --diagnose=${{matrix.diagnose}} diff --git a/.github/workflows/run-step.py b/.github/workflows/run-step.py new file mode 100644 index 0000000..470990b --- /dev/null +++ b/.github/workflows/run-step.py @@ -0,0 +1,222 @@ +import argparse +import os +import platform +import subprocess + + +source_root = os.path.normpath( + os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "..", "..")) + +ubuntu_test_toolchain_ppa = "ppa:ubuntu-toolchain-r/test" + +tests = [ + { "cmd": ["asmjit_test_unit", "--quick"] }, + { "cmd": ["asmjit_test_opcode", "--quiet"] }, + { "cmd": ["asmjit_test_x86_asm"] }, + { "cmd": ["asmjit_test_x86_sections"] }, + { "cmd": ["asmjit_test_x86_instinfo"] }, + { "cmd": ["asmjit_test_compiler"] } +] + +sanitize_macro = "ASMJIT_SANITIZE" + +valgrind_args = [ + "valgrind", + "--leak-check=full", + "--show-reachable=yes", + "--track-origins=yes" +] + + +def log(message): + print(message, flush=True) + + +def run(args, cwd=None, env=None, sudo=False, print_command=True): + if sudo: + args = ["sudo"] + args + + if print_command: + log(" ".join(args)) + + subprocess.run(args, cwd=cwd, env=env, check=True) + + +def main(): + parser = argparse.ArgumentParser(description="Step executor") + + parser.add_argument("--step", default=None, help="Step to execute (prepare|configure|build|test)") + parser.add_argument("--compiler", default="", help="C++ compiler to use") + parser.add_argument("--generator", default="", help="CMake generator to use") + parser.add_argument("--architecture", default="default", help="Target architecture") + parser.add_argument("--build-dir", default="build", help="Build directory") + parser.add_argument("--build-type", default="", help="Build type (Debug / Release)") + parser.add_argument("--build-defs", default="", help="Build definitions") + parser.add_argument("--diagnose", default="", help="Diagnostics (valgrind|address|undefined)") + + args = parser.parse_args() + step = args.step + compiler = args.compiler + generator = args.generator + architecture = args.architecture.lower() + diagnose = args.diagnose + + platform_name = platform.system() + + if not compiler: + compiler = "" + + if not generator: + if compiler == "vs2015": + generator = "Visual Studio 14 2015" + elif compiler == "vs2017": + generator = "Visual Studio 15 2017" + elif compiler == "vs2019": + generator = "Visual Studio 16 2019" + elif platform_name == "Darwin": + generator = "Unix Makefiles" + else: + generator = "Ninja" + + + # --------------------------------------------------------------------------- + if step == "prepare": + if platform_name == "Windows": + pass + + elif platform_name == "Darwin": + pass + + elif platform_name == "Linux": + if compiler.startswith("gcc"): + compiler_package = compiler.replace("gcc", "g++") + elif compiler.startswith("clang"): + compiler_package = compiler + else: + raise ValueError("Invalid compiler: {}".format(compiler)) + + apt_packages = [compiler_package] + + if generator == "Ninja": + apt_packages.append("ninja-build") + + if architecture == "x86": + run(["dpkg", "--add-architecture", "i386"], sudo=True) + apt_packages.append("linux-libc-dev:i386") + if compiler.startswith("gcc"): + apt_packages.append(compiler_package + "-multilib") + else: + apt_packages.append("g++-multilib") # Even clang requires this. + + if diagnose == "valgrind": + apt_packages.append("valgrind") + + run(["apt-add-repository", "-y", ubuntu_test_toolchain_ppa], sudo=True) + run(["apt-get", "update", "-qq"], sudo=True) + run(["apt-get", "install", "-qq"] + apt_packages, sudo=True) + + else: + raise ValueError("Unknown platform: {}".format(platform_name)) + + exit(0) + # --------------------------------------------------------------------------- + + + # --------------------------------------------------------------------------- + if step == "configure": + os.makedirs(args.build_dir, exist_ok=True) + + cmd = ["cmake", source_root, "-G" + generator] + env = os.environ.copy() + + if generator.startswith("Visual Studio"): + if architecture == "x86": + cmd.extend(["-A", "Win32"]) + else: + cmd.extend(["-A", "x64"]) + else: + if compiler.startswith("gcc"): + cc_bin = compiler + cxx_bin = compiler.replace("gcc", "g++") + elif compiler.startswith("clang"): + cc_bin = compiler + cxx_bin = compiler.replace("clang", "clang++") + else: + raise ValueError("Invalid compiler: {}".format(compiler)) + + env["CC"] = cc_bin + env["CXX"] = cxx_bin + + if architecture == "x86": + env["CFLAGS"] = "-m32" + env["CXXFLAGS"] = "-m32" + env["LDFLAGS"] = "-m32" + + if args.build_type: + cmd.append("-DCMAKE_BUILD_TYPE=" + args.build_type) + + if args.build_defs: + for build_def in args.build_defs.split(","): + cmd.append("-D" + build_def) + + if diagnose and diagnose != "valgrind": + cmd.append("-D" + sanitize_macro + "=" + diagnose) + + run(cmd, cwd=args.build_dir, env=env) + exit(0) + # --------------------------------------------------------------------------- + + + # --------------------------------------------------------------------------- + if step == "build": + cmd = ["cmake", "--build", "."] + + if generator.startswith("Visual Studio"): + cmd.extend(["--config", args.build_type, "--", "-nologo", "-v:minimal"]) + + run(cmd, cwd=args.build_dir) + exit(0) + # --------------------------------------------------------------------------- + + + # --------------------------------------------------------------------------- + if step == "test": + build_dir = args.build_dir + build_type = args.build_type + + # Multi-Configuration build use a nested directory. + if os.path.isdir(os.path.join(build_dir, build_type)): + build_dir = os.path.join(build_dir, build_type) + + for test in tests: + cmd = [] + test["cmd"] + test_name = cmd[0] + executable = os.path.abspath(os.path.join(build_dir, cmd[0])) + + if platform_name == "Windows": + executable += ".exe" + + # Ignore tests, which were not built, because of disabled features. + if os.path.isfile(executable): + try: + log("::group::" + test_name) + log(" ".join(cmd)) + + if diagnose == "valgrind": + cmd = valgrind_args + cmd + + cmd[0] = executable + run(cmd, cwd=build_dir, print_command=False) + finally: + log("::endgroup::") + + exit(0) + # --------------------------------------------------------------------------- + + raise ValueError("Invalid step: {}".format(step)) + + +if __name__ == "__main__": + main() diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 42e79a6..0000000 --- a/.travis.yml +++ /dev/null @@ -1,334 +0,0 @@ -language: cpp - -git: - depth: false - -env: - global: - - BUILD_TOOLCHAIN="Unix Makefiles" - - MAKEFLAGS="-j2" - -dist: bionic - -matrix: - include: - - name: "Source Code Check" - env: BUILD_MATRIX="SOURCE_CODE_CHECK=1" - os: linux - language: node_js - node_js: - - node - - - name: "Linux Clang Default [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=clang-9 && CXX=clang++-9" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux Clang Default [X64] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux Clang Default [X64] [REL] [Valgrind]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" USE_VALGRIND=1 - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9, valgrind] - - - name: "Linux Clang Default [X64] [REL] [Sanitize=Address]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" EXTRA_OPTIONS="-DASMJIT_SANITIZE=address" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux Clang Default [X64] [REL] [Sanitize=Undefined]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" EXTRA_OPTIONS="-DASMJIT_SANITIZE=undefined" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux Clang Default [X64] [REL] [NoDeprecated]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" EXTRA_OPTIONS="-DASMJIT_NO_DEPRECATED=1" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux Clang Default [X64] [REL] [NoIntrinsics]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" EXTRA_OPTIONS="-DASMJIT_NO_INTRINSICS=1" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux Clang Default [X64] [REL] [NoLogging]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" EXTRA_OPTIONS="-DASMJIT_NO_LOGGING=1" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux Clang Default [X64] [REL] [NoBuilder]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" EXTRA_OPTIONS="-DASMJIT_NO_BUILDER=1" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux Clang Default [X64] [REL] [NoCompiler]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=clang-9 && CXX=clang++-9" EXTRA_OPTIONS="-DASMJIT_NO_COMPILER=1" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [clang++-9] - - - name: "Linux GCC 4.8 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-4.8 && CXX=g++-4.8" CXXFLAGS=-m32 LDFLAGS=-m32 - os: linux - addons: - apt: - packages: [g++-4.8, g++-4.8-multilib, "linux-libc-dev:i386"] - - - name: "Linux GCC 4.8 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-4.8 && CXX=g++-4.8" - os: linux - addons: - apt: - packages: [g++-4.8] - - - name: "Linux GCC 5 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-5 && CXX=g++-5" CXXFLAGS=-m32 LDFLAGS=-m32 - os: linux - addons: - apt: - packages: [g++-5, g++-5-multilib, "linux-libc-dev:i386"] - - - name: "Linux GCC 5 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-5 && CXX=g++-5" - os: linux - addons: - apt: - packages: [g++-5] - - - name: "Linux GCC 6 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-6 && CXX=g++-6" CXXFLAGS=-m32 LDFLAGS=-m32 - os: linux - addons: - apt: - packages: [g++-6, g++-6-multilib, "linux-libc-dev:i386"] - - - name: "Linux GCC 6 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-6 && CXX=g++-6" - os: linux - addons: - apt: - packages: [g++-6] - - - name: "Linux GCC 7 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-7 && CXX=g++-7" CXXFLAGS=-m32 LDFLAGS=-m32 - os: linux - addons: - apt: - packages: [g++-7, g++-7-multilib, "linux-libc-dev:i386"] - - - name: "Linux GCC 7 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-7 && CXX=g++-7" - os: linux - addons: - apt: - packages: [g++-7] - - - name: "Linux GCC 8 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-8 && CXX=g++-8" CXXFLAGS=-m32 LDFLAGS=-m32 - os: linux - addons: - apt: - packages: [g++-8, g++-8-multilib, "linux-libc-dev:i386"] - - - name: "Linux GCC 8 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-8 && CXX=g++-8" - os: linux - addons: - apt: - packages: [g++-8] - - - name: "Linux GCC 9 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-9 && CXX=g++-9" CXXFLAGS=-m32 LDFLAGS=-m32 - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [g++-9, g++-9-multilib, "linux-libc-dev:i386"] - - - name: "Linux GCC 9 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-9 && CXX=g++-9" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [g++-9] - - - name: "Linux GCC 10 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-10 && CXX=g++-10" CXXFLAGS=-m32 LDFLAGS=-m32 - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [g++-10, g++-10-multilib, "linux-libc-dev:i386"] - - - name: "Linux GCC 10 [X86] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-10 && CXX=g++-10" CXXFLAGS=-m32 LDFLAGS=-m32 - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [g++-10, g++-10-multilib, "linux-libc-dev:i386"] - - - name: "Linux GCC 10 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug && CC=gcc-10 && CXX=g++-10" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [g++-10] - - - name: "Linux GCC 10 [X64] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release && CC=gcc-10 && CXX=g++-10" - os: linux - addons: - apt: - sources: - - sourceline: "ppa:ubuntu-toolchain-r/test" - packages: [g++-10] - - - name: "Linux GCC Default [ARM64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug" - os: linux - arch: arm64 - - - name: "Linux GCC Default [ARM64] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release" - os: linux - arch: arm64 - - - name: "OSX Clang XCode 9.4 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug" CXXFLAGS=-m32 LDFLAGS=-m32 - os: osx - osx_image: xcode9.4 - - - name: "OSX Clang XCode 9.4 [X86] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release" CXXFLAGS=-m32 LDFLAGS=-m32 - os: osx - osx_image: xcode9.4 - - - name: "OSX Clang XCode 9.4 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug" - os: osx - osx_image: xcode9.4 - - - name: "OSX Clang XCode 9.4 [X64] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release" - os: osx - osx_image: xcode9.4 - - - name: "OSX Clang XCode 10.2 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug" - os: osx - osx_image: xcode10.2 - - - name: "OSX Clang XCode 10.2 [X64] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release" - os: osx - osx_image: xcode10.2 - - - name: "OSX Clang XCode 11 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug" - os: osx - osx_image: xcode11 - - - name: "OSX Clang XCode 11 [X64] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release" - os: osx - osx_image: xcode11 - - - name: "Windows VS2017 [X86] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug" BUILD_TOOLCHAIN="Visual Studio 15 2017" - os: windows - - - name: "Windows VS2017 [X86] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release" BUILD_TOOLCHAIN="Visual Studio 15 2017" - os: windows - - - name: "Windows VS2017 [X64] [DBG]" - env: BUILD_MATRIX="BUILD_TYPE=Debug" BUILD_TOOLCHAIN="Visual Studio 15 2017 Win64" - os: windows - - - name: "Windows VS2017 [X64] [REL]" - env: BUILD_MATRIX="BUILD_TYPE=Release" BUILD_TOOLCHAIN="Visual Studio 15 2017 Win64" - os: windows - -before_install: - - eval "$BUILD_MATRIX" - -before_script: - - | - if [ -z $SOURCE_CODE_CHECK ]; then - mkdir build - cd build - if [[ "$BUILD_TOOLCHAIN" =~ ^Visual\ Studio ]]; then - cmake .. -G"${BUILD_TOOLCHAIN}" -DASMJIT_TEST=1 ${EXTRA_OPTIONS} - else - cmake .. -G"${BUILD_TOOLCHAIN}" -DASMJIT_TEST=1 ${EXTRA_OPTIONS} -DCMAKE_PREFIX_PATH="${MINGW_PATH}" -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" - fi - cd .. - fi - -script: - - | - if [ -z $SOURCE_CODE_CHECK ]; then - ROOT_DIR=`pwd` - cd build - if [[ "$BUILD_TOOLCHAIN" =~ ^Visual\ Studio ]]; then - cmake --build . --config ${BUILD_TYPE} -- -nologo -v:minimal || exit 1 - cd ${BUILD_TYPE} - else - cmake --build . || exit 1 - fi - ${ROOT_DIR}/tools/ci-run.sh . || exit 1 - else - cd tools - ./enumgen.sh --verify || exit 1 - cd .. - fi diff --git a/src/asmjit/core/globals.cpp b/src/asmjit/core/globals.cpp index c7d1f72..dc5083b 100644 --- a/src/asmjit/core/globals.cpp +++ b/src/asmjit/core/globals.cpp @@ -104,6 +104,7 @@ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept { "OverlappingStackRegWithRegArg\0" "ExpressionLabelNotBound\0" "ExpressionOverflow\0" + "FailedToOpenAnonymousMemory\0" "\0"; static const uint16_t sErrorIndex[] = { @@ -111,7 +112,7 @@ ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept { 247, 264, 283, 313, 328, 344, 363, 382, 400, 422, 440, 459, 474, 490, 504, 518, 538, 563, 581, 603, 625, 642, 659, 675, 691, 707, 724, 739, 754, 774, 794, 814, 847, 867, 882, 899, 918, 939, 959, 973, 994, 1008, 1026, 1042, - 1058, 1077, 1092, 1108, 1123, 1138, 1168, 1192, 1211 + 1058, 1077, 1092, 1108, 1123, 1138, 1168, 1192, 1211, 1239 }; // @EnumStringEnd@ diff --git a/src/asmjit/core/globals.h b/src/asmjit/core/globals.h index c1535e1..3b7bfc9 100644 --- a/src/asmjit/core/globals.h +++ b/src/asmjit/core/globals.h @@ -379,6 +379,9 @@ enum ErrorCode : uint32_t { //! Arithmetic overflow during expression evaluation. kErrorExpressionOverflow, + //! Failed to open anonymous memory handle or file descriptor. + kErrorFailedToOpenAnonymousMemory, + // @EnumValuesEnd@ //! Count of AsmJit error codes. diff --git a/src/asmjit/core/support.h b/src/asmjit/core/support.h index 22a0fa0..1668389 100644 --- a/src/asmjit/core/support.h +++ b/src/asmjit/core/support.h @@ -218,9 +218,8 @@ static constexpr T lsbMask(const CountT& n) noexcept { return (sizeof(U) < sizeof(uintptr_t)) // Prevent undefined behavior by using a larger type than T. ? T(U((uintptr_t(1) << n) - uintptr_t(1))) - // Prevent undefined behavior by performing `n & (nBits - 1)` so it's always within the range. - : shr(sar(neg(T(n)), bitSizeOf() - 1u), - neg(T(n)) & CountT(bitSizeOf() - 1u)); + // Prevent undefined behavior by checking `n` before shift. + : n ? T(shr(allOnes(), bitSizeOf() - size_t(n))) : T(0); } //! Tests whether the given value `x` has `n`th bit set. diff --git a/src/asmjit/core/virtmem.cpp b/src/asmjit/core/virtmem.cpp index 8f7d9a8..a1b0f95 100644 --- a/src/asmjit/core/virtmem.cpp +++ b/src/asmjit/core/virtmem.cpp @@ -219,16 +219,50 @@ Error VirtMem::releaseDualMapping(DualMapping* dm, size_t size) noexcept { // ============================================================================ #if !defined(_WIN32) -struct ScopedFD { - inline ScopedFD() noexcept - : value(-1) {} +class AnonymousMemory { +public: + enum FileType : uint32_t { + kFileTypeNone, + kFileTypeTmp, + kFileTypeShm + }; - inline ~ScopedFD() noexcept { - if (value != -1) - close(value); + int fd; + FileType fileType; + StringTmp<128> tmpName; + + AnonymousMemory() noexcept + : fd(-1), + fileType(kFileTypeNone), + tmpName() {} + + ~AnonymousMemory() noexcept { + unlinkFile(); + closeFile(); } - int value; + int closeFile() noexcept { + if (fd >= 0) { + int result = close(fd); + fd = -1; + return result; + } + else { + return 0; + } + } + + int unlinkFile() noexcept { + FileType type = fileType; + fileType = kFileTypeNone; + + if (type == kFileTypeTmp) + return unlink(tmpName.data()); + else if (type == kFileTypeShm) + return shm_unlink(tmpName.data()); + else + return 0; + } }; static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept { @@ -333,7 +367,7 @@ static ASMJIT_INLINE bool VirtMem_hasMapJitSupport() noexcept { #endif } -static ASMJIT_INLINE int VirtMem_appleSpecificMMapFlags(uint32_t flags) { +static ASMJIT_INLINE int VirtMem_appleSpecificMMapFlags(uint32_t flags) noexcept { // Always use MAP_JIT flag if user asked for it (could be used for testing // on non-hardened processes) and detect whether it must be used when the // process is actually hardened (in that case it doesn't make sense to rely @@ -345,7 +379,7 @@ static ASMJIT_INLINE int VirtMem_appleSpecificMMapFlags(uint32_t flags) { return 0; } #else -static ASMJIT_INLINE int VirtMem_appleSpecificMMapFlags(uint32_t flags) { +static ASMJIT_INLINE int VirtMem_appleSpecificMMapFlags(uint32_t flags) noexcept { DebugUtils::unused(flags); return 0; } @@ -358,7 +392,7 @@ static const char* VirtMem_getTmpDir() noexcept { } #endif -static Error VirtMem_openAnonymousMemory(int* fd, bool preferTmpOverDevShm) noexcept { +static Error VirtMem_openAnonymousMemory(AnonymousMemory* anonMem, bool preferTmpOverDevShm) noexcept { #if defined(SYS_memfd_create) // Linux specific 'memfd_create' - if the syscall returns `ENOSYS` it means // it's not available and we will never call it again (would be pointless). @@ -368,8 +402,8 @@ static Error VirtMem_openAnonymousMemory(int* fd, bool preferTmpOverDevShm) noex static volatile uint32_t memfd_create_not_supported; if (!memfd_create_not_supported) { - *fd = (int)syscall(SYS_memfd_create, "vmem", 0); - if (ASMJIT_LIKELY(*fd >= 0)) + anonMem->fd = (int)syscall(SYS_memfd_create, "vmem", 0); + if (ASMJIT_LIKELY(anonMem->fd >= 0)) return kErrorOk; int e = errno; @@ -383,9 +417,9 @@ static Error VirtMem_openAnonymousMemory(int* fd, bool preferTmpOverDevShm) noex #if defined(SHM_ANON) // Originally FreeBSD extension, apparently works in other BSDs too. DebugUtils::unused(preferTmpOverDevShm); - *fd = shm_open(SHM_ANON, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + anonMem->fd = shm_open(SHM_ANON, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (ASMJIT_LIKELY(*fd >= 0)) + if (ASMJIT_LIKELY(anonMem->fd >= 0)) return kErrorOk; else return DebugUtils::errored(VirtMem_makeErrorFromErrno(errno)); @@ -396,55 +430,52 @@ static Error VirtMem_openAnonymousMemory(int* fd, bool preferTmpOverDevShm) noex // and retries for avoiding collisions. We use `shm_open()` with flags that // require creation of the file so we never open an existing shared memory. static std::atomic internalCounter; - - StringTmp<128> uniqueName; - const char* kShmFormat = "/shm-id-%08llX"; + const char* kShmFormat = "/shm-id-%016llX"; uint32_t kRetryCount = 100; - uint64_t bits = ((uintptr_t)(void*)&uniqueName) & 0x55555555u; + uint64_t bits = ((uintptr_t)(void*)anonMem) & 0x55555555u; for (uint32_t i = 0; i < kRetryCount; i++) { bits -= uint64_t(OSUtils::getTickCount()) * 773703683; bits = ((bits >> 14) ^ (bits << 6)) + uint64_t(++internalCounter) * 10619863; if (!ASMJIT_VM_SHM_DETECT || preferTmpOverDevShm) { - uniqueName.assign(VirtMem_getTmpDir()); - uniqueName.appendFormat(kShmFormat, (unsigned long long)bits); - *fd = open(uniqueName.data(), O_RDWR | O_CREAT | O_EXCL, 0); - if (ASMJIT_LIKELY(*fd >= 0)) { - unlink(uniqueName.data()); + anonMem->tmpName.assign(VirtMem_getTmpDir()); + anonMem->tmpName.appendFormat(kShmFormat, (unsigned long long)bits); + anonMem->fd = open(anonMem->tmpName.data(), O_RDWR | O_CREAT | O_EXCL, 0); + if (ASMJIT_LIKELY(anonMem->fd >= 0)) { + anonMem->fileType = AnonymousMemory::kFileTypeTmp; return kErrorOk; } } else { - uniqueName.assignFormat(kShmFormat, (unsigned long long)bits); - *fd = shm_open(uniqueName.data(), O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (ASMJIT_LIKELY(*fd >= 0)) { - shm_unlink(uniqueName.data()); + anonMem->tmpName.assignFormat(kShmFormat, (unsigned long long)bits); + anonMem->fd = shm_open(anonMem->tmpName.data(), O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + if (ASMJIT_LIKELY(anonMem->fd >= 0)) { + anonMem->fileType = AnonymousMemory::kFileTypeShm; return kErrorOk; } } int e = errno; - if (e == EEXIST) - continue; - else + if (e != EEXIST) return DebugUtils::errored(VirtMem_makeErrorFromErrno(e)); } - return kErrorOk; + + return DebugUtils::errored(kErrorFailedToOpenAnonymousMemory); #endif } #if ASMJIT_VM_SHM_DETECT static Error VirtMem_detectShmStrategy(uint32_t* strategyOut) noexcept { - ScopedFD fd; + AnonymousMemory anonMem; VirtMem::Info vmInfo = VirtMem::info(); - ASMJIT_PROPAGATE(VirtMem_openAnonymousMemory(&fd.value, false)); - if (ftruncate(fd.value, off_t(vmInfo.pageSize)) != 0) + ASMJIT_PROPAGATE(VirtMem_openAnonymousMemory(&anonMem, false)); + if (ftruncate(anonMem.fd, off_t(vmInfo.pageSize)) != 0) return DebugUtils::errored(VirtMem_makeErrorFromErrno(errno)); - void* ptr = mmap(nullptr, vmInfo.pageSize, PROT_READ | PROT_EXEC, MAP_SHARED, fd.value, 0); + void* ptr = mmap(nullptr, vmInfo.pageSize, PROT_READ | PROT_EXEC, MAP_SHARED, anonMem.fd, 0); if (ptr == MAP_FAILED) { int e = errno; if (e == EINVAL) { @@ -530,15 +561,14 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no preferTmpOverDevShm = (strategy == kShmStrategyTmpDir); } - // ScopedFD will automatically close the file descriptor in its destructor. - ScopedFD fd; - ASMJIT_PROPAGATE(VirtMem_openAnonymousMemory(&fd.value, preferTmpOverDevShm)); - if (ftruncate(fd.value, off_t(size)) != 0) + AnonymousMemory anonMem; + ASMJIT_PROPAGATE(VirtMem_openAnonymousMemory(&anonMem, preferTmpOverDevShm)); + if (ftruncate(anonMem.fd, off_t(size)) != 0) return DebugUtils::errored(VirtMem_makeErrorFromErrno(errno)); void* ptr[2]; for (uint32_t i = 0; i < 2; i++) { - ptr[i] = mmap(nullptr, size, VirtMem_accessToPosixProtection(flags & ~VirtMem_dualMappingFilter[i]), MAP_SHARED, fd.value, 0); + ptr[i] = mmap(nullptr, size, VirtMem_accessToPosixProtection(flags & ~VirtMem_dualMappingFilter[i]), MAP_SHARED, anonMem.fd, 0); if (ptr[i] == MAP_FAILED) { // Get the error now before `munmap` has a chance to clobber it. int e = errno; diff --git a/test/asmjit_bench_x86.cpp b/test/asmjit_bench_x86.cpp index 590419c..6f75916 100644 --- a/test/asmjit_bench_x86.cpp +++ b/test/asmjit_bench_x86.cpp @@ -30,10 +30,10 @@ #include #include -#include "./asmjit_test_opcode.h" +#include "asmjit_test_opcode.h" #ifndef ASMJIT_NO_COMPILER - #include "./asmjit_test_misc.h" + #include "asmjit_test_misc.h" #endif using namespace asmjit; diff --git a/test/asmjit_test_compiler.cpp b/test/asmjit_test_compiler.cpp index 6a83e7c..45adb70 100644 --- a/test/asmjit_test_compiler.cpp +++ b/test/asmjit_test_compiler.cpp @@ -30,8 +30,8 @@ #include #include -#include "./cmdline.h" -#include "./asmjit_test_compiler.h" +#include "cmdline.h" +#include "asmjit_test_compiler.h" #if defined(ASMJIT_BUILD_X86) && ASMJIT_ARCH_X86 #include diff --git a/test/asmjit_test_compiler_x86.cpp b/test/asmjit_test_compiler_x86.cpp index 4caa7d8..bc32314 100644 --- a/test/asmjit_test_compiler_x86.cpp +++ b/test/asmjit_test_compiler_x86.cpp @@ -33,8 +33,8 @@ // Required for function tests that pass / return XMM registers. #include -#include "./asmjit_test_misc.h" -#include "./asmjit_test_compiler.h" +#include "asmjit_test_misc.h" +#include "asmjit_test_compiler.h" #ifdef _MSC_VER // Interaction between '_setjmp' and C++ object destruction is non-portable. diff --git a/test/asmjit_test_opcode.cpp b/test/asmjit_test_opcode.cpp index 939cb78..1cd67e2 100644 --- a/test/asmjit_test_opcode.cpp +++ b/test/asmjit_test_opcode.cpp @@ -31,7 +31,8 @@ #include #include -#include "./asmjit_test_opcode.h" +#include "cmdline.h" +#include "asmjit_test_opcode.h" using namespace asmjit; @@ -63,7 +64,8 @@ struct TestErrorHandler : public ErrorHandler { typedef void (*VoidFunc)(void); -int main() { +int main(int argc, char* argv[]) { + CmdLine cmdLine(argc, argv); TestErrorHandler eh; OpcodeDumpInfo infoList[] = { @@ -74,6 +76,8 @@ int main() { { Environment::kArchX64, true , true } }; + bool quiet = cmdLine.hasArg("--quiet"); + for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(infoList); i++) { const OpcodeDumpInfo& info = infoList[i]; @@ -89,7 +93,8 @@ int main() { #ifndef ASMJIT_NO_LOGGING FileLogger logger(stdout); logger.addFlags(FormatOptions::kFlagMachineCode); - code.setLogger(&logger); + if (!quiet) + code.setLogger(&logger); #endif x86::Assembler a(&code); diff --git a/tools/ci-run.sh b/tools/ci-run.sh deleted file mode 100755 index e7d9278..0000000 --- a/tools/ci-run.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env sh - -set -e - -BUILD_DIR=$1 - -if [ "$USE_VALGRIND" = "1" ]; then - RUN_CMD="valgrind --leak-check=full --show-reachable=yes --track-origins=yes" -fi - -echo "" -echo "=== Starting Tests ===" - -echo "" -eval "$RUN_CMD ${BUILD_DIR}/asmjit_test_unit --quick" - -echo "" -echo "AsmJit Opcode Test" -eval "$RUN_CMD ${BUILD_DIR}/asmjit_test_opcode > /dev/null" - -if [ -f ${BUILD_DIR}/asmjit_test_x86_asm ]; then - echo "" - eval "$RUN_CMD ${BUILD_DIR}/asmjit_test_x86_asm" -fi - -if [ -f ${BUILD_DIR}/asmjit_test_x86_sections ]; then - echo "" - eval "$RUN_CMD ${BUILD_DIR}/asmjit_test_x86_sections" -fi - -if [ -f ${BUILD_DIR}/asmjit_test_x86_instinfo ]; then - echo "" - eval "$RUN_CMD ${BUILD_DIR}/asmjit_test_x86_instinfo" -fi - -if [ -f ${BUILD_DIR}asmjit_test_compiler ]; then - echo "" - eval "$RUN_CMD ${BUILD_DIR}/asmjit_test_compiler" -fi