Imported Upstream version 1.11.0+dfsg1

This commit is contained in:
Ximin Luo 2016-08-22 23:21:25 +02:00
parent a7813a04b4
commit 3157f602e5
1604 changed files with 50472 additions and 25030 deletions

View File

@ -108,7 +108,8 @@ root.
There are large number of options accepted by this script to alter the There are large number of options accepted by this script to alter the
configuration used later in the build process. Some options to note: configuration used later in the build process. Some options to note:
- `--enable-debug` - Build a debug version of the compiler (disables optimizations) - `--enable-debug` - Build a debug version of the compiler (disables optimizations,
which speeds up compilation of stage1 rustc)
- `--enable-optimize` - Enable optimizations (can be used with `--enable-debug` - `--enable-optimize` - Enable optimizations (can be used with `--enable-debug`
to make a debug build with optimizations) to make a debug build with optimizations)
- `--disable-valgrind-rpass` - Don't run tests with valgrind - `--disable-valgrind-rpass` - Don't run tests with valgrind
@ -122,10 +123,18 @@ To see a full list of options, run `./configure --help`.
Some common make targets are: Some common make targets are:
- `make tips` - show useful targets, variables and other tips for working with
the build system.
- `make rustc-stage1` - build up to (and including) the first stage. For most - `make rustc-stage1` - build up to (and including) the first stage. For most
cases we don't need to build the stage2 compiler, so we can save time by not cases we don't need to build the stage2 compiler, so we can save time by not
building it. The stage1 compiler is a fully functioning compiler and building it. The stage1 compiler is a fully functioning compiler and
(probably) will be enough to determine if your change works as expected. (probably) will be enough to determine if your change works as expected.
- `make $host/stage1/bin/rustc` - Where $host is a target triple like x86_64-unknown-linux-gnu.
This will build just rustc, without libstd. This is the fastest way to recompile after
you changed only rustc source code. Note however that the resulting rustc binary
won't have a stdlib to link against by default. You can build libstd once with
`make rustc-stage1`, rustc will pick it up afterwards. libstd is only guaranteed to
work if recompiled, so if there are any issues recompile it.
- `make check` - build the full compiler & run all tests (takes a while). This - `make check` - build the full compiler & run all tests (takes a while). This
is what gets run by the continuous integration system against your pull is what gets run by the continuous integration system against your pull
request. You should run this before submitting to make sure your tests pass request. You should run this before submitting to make sure your tests pass

View File

@ -62,6 +62,8 @@
# * tidy - Basic style check, show highest rustc error code and # * tidy - Basic style check, show highest rustc error code and
# the status of language and lib features # the status of language and lib features
# * rustc-stage$(stage) - Only build up to a specific stage # * rustc-stage$(stage) - Only build up to a specific stage
# * $host/stage1/bin/rustc - Only build stage1 rustc, not libstd. For further
# information see "Rust recipes for build system success" below.
# #
# Then mix in some of these environment variables to harness the # Then mix in some of these environment variables to harness the
# ultimate power of The Rust Build System. # ultimate power of The Rust Build System.
@ -93,6 +95,15 @@
# // Modifying libstd? Use this command to run unit tests just on your change # // Modifying libstd? Use this command to run unit tests just on your change
# make check-stage1-std NO_REBUILD=1 NO_BENCH=1 # make check-stage1-std NO_REBUILD=1 NO_BENCH=1
# #
# // Modifying just rustc?
# // Compile rustc+libstd once
# make rustc-stage1
# // From now on use this command to rebuild just rustc and reuse the previously built libstd
# // $host is a target triple, eg. x86_64-unknown-linux-gnu
# // The resulting binary is located at $host/stage1/bin/rustc.
# // If there are any issues with libstd recompile it with the command above.
# make $host/stage1/bin/rustc
#
# // Added a run-pass test? Use this to test running your test # // Added a run-pass test? Use this to test running your test
# make check-stage1-rpass TESTNAME=my-shiny-new-test # make check-stage1-rpass TESTNAME=my-shiny-new-test
# #
@ -266,13 +277,17 @@ endif
# CTAGS building # CTAGS building
ifneq ($(strip $(findstring TAGS.emacs,$(MAKECMDGOALS)) \ ifneq ($(strip $(findstring TAGS.emacs,$(MAKECMDGOALS)) \
$(findstring TAGS.vi,$(MAKECMDGOALS))),) $(findstring TAGS.vi,$(MAKECMDGOALS)) \
$(findstring TAGS.rustc.emacs,$(MAKECMDGOALS)) \
$(findstring TAGS.rustc.vi,$(MAKECMDGOALS))),)
CFG_INFO := $(info cfg: including ctags rules) CFG_INFO := $(info cfg: including ctags rules)
include $(CFG_SRC_DIR)mk/ctags.mk include $(CFG_SRC_DIR)mk/ctags.mk
endif endif
.DEFAULT: .DEFAULT:
@echo "\n======================================================" @echo
@echo "======================================================"
@echo "== If you need help, run 'make help' or 'make tips' ==" @echo "== If you need help, run 'make help' or 'make tips' =="
@echo "======================================================\n" @echo "======================================================"
@echo
exit 1 exit 1

View File

@ -1,7 +1,7 @@
# The Rust Programming Language # The Rust Programming Language
This is the main source code repository for [Rust]. It contains the compiler, standard library, This is the main source code repository for [Rust]. It contains the compiler,
and documentation. standard library, and documentation.
[Rust]: https://www.rust-lang.org [Rust]: https://www.rust-lang.org
@ -19,6 +19,7 @@ Read ["Installing Rust"] from [The Book].
* `g++` 4.7 or later or `clang++` 3.x * `g++` 4.7 or later or `clang++` 3.x
* `python` 2.7 (but not 3.x) * `python` 2.7 (but not 3.x)
* GNU `make` 3.81 or later * GNU `make` 3.81 or later
* `cmake` 2.8.8 or later
* `curl` * `curl`
* `git` * `git`
@ -63,35 +64,37 @@ build.
#### MinGW #### MinGW
[MSYS2](http://msys2.github.io/) can be used to easily build Rust on Windows: [MSYS2][msys2] can be used to easily build Rust on Windows:
1. Grab the latest MSYS2 installer and go through the installer. msys2: https://msys2.github.io/
2. From the MSYS2 terminal, install the `mingw64` toolchain and other required 1. Grab the latest [MSYS2 installer][msys2] and go through the installer.
tools.
2. Run `mingw32_shell.bat` or `mingw64_shell.bat` from wherever you installed
MSYS2 (i.e. `C:\msys64`), depending on whether you want 32-bit or 64-bit
Rust. (As of the latest version of MSYS2 you have to run `msys2_shell.cmd
-mingw32` or `msys2_shell.cmd -mingw64` from the command line instead)
3. From this terminal, install the required tools:
```sh ```sh
# Update package mirrors (may be needed if you have a fresh install of MSYS2) # Update package mirrors (may be needed if you have a fresh install of MSYS2)
$ pacman -Sy pacman-mirrors $ pacman -Sy pacman-mirrors
# Install build tools needed for Rust. If you're building a 32-bit compiler,
# then replace "x86_64" below with "i686". If you've already got git, python,
# or CMake installed and in PATH you can remove them from this list. Note
# that it is important that the `python2` and `cmake` packages **not** used.
# The build has historically been known to fail with these packages.
$ pacman -S git \
make \
diffutils \
mingw-w64-x86_64-python2 \
mingw-w64-x86_64-cmake \
mingw-w64-x86_64-gcc
``` ```
Download [MinGW from 4. Navigate to Rust's source code (or clone it), then configure and build it:
here](http://mingw-w64.org/doku.php/download/mingw-builds), and choose the
`version=4.9.x,threads=win32,exceptions=dwarf/seh` flavor when installing. Also, make sure to install to a path without spaces in it. After installing,
add its `bin` directory to your `PATH`. This is due to [#28260](https://github.com/rust-lang/rust/issues/28260), in the future,
installing from pacman should be just fine.
```
# Make git available in MSYS2 (if not already available on path)
$ pacman -S git
$ pacman -S base-devel
```
3. Run `mingw32_shell.bat` or `mingw64_shell.bat` from wherever you installed
MSYS2 (i.e. `C:\msys`), depending on whether you want 32-bit or 64-bit Rust.
4. Navigate to Rust's source code, configure and build it:
```sh ```sh
$ ./configure $ ./configure
@ -111,12 +114,25 @@ $ ./configure
$ make && make install $ make && make install
``` ```
#### MSVC with rustbuild
For those who don't want the hassle of MSYS or MinGW, you can invoke rustbuild
directly. All you need are Python 2, CMake, and Git in your PATH (make sure you
do __not__ use the ones from MSYS!). You'll also need Visual Studio 2013 or
newer with the C++ tools. Then all you need to do is invoke the appropriate
vcvars bat file and kick off rustbuild.
```bat
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"
python .\src\bootstrap\bootstrap.py
```
## Building Documentation ## Building Documentation
If youd like to build the documentation, its almost the same: If youd like to build the documentation, its almost the same:
```sh ```sh
./configure $ ./configure
$ make docs $ make docs
``` ```
@ -151,8 +167,8 @@ Snapshot binaries are currently built and tested on several platforms:
You may find that other platforms work, but these are our officially You may find that other platforms work, but these are our officially
supported build environments that are most likely to work. supported build environments that are most likely to work.
Rust currently needs between 600MiB and 1.5GiB to build, depending on platform. If it hits Rust currently needs between 600MiB and 1.5GiB to build, depending on platform.
swap, it will take a very long time to build. If it hits swap, it will take a very long time to build.
There is more advice about hacking on Rust in [CONTRIBUTING.md]. There is more advice about hacking on Rust in [CONTRIBUTING.md].
@ -189,4 +205,5 @@ Rust is primarily distributed under the terms of both the MIT license
and the Apache License (Version 2.0), with portions covered by various and the Apache License (Version 2.0), with portions covered by various
BSD-like licenses. BSD-like licenses.
See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and [COPYRIGHT](COPYRIGHT) for details. See [LICENSE-APACHE](LICENSE-APACHE), [LICENSE-MIT](LICENSE-MIT), and
[COPYRIGHT](COPYRIGHT) for details.

398
configure vendored
View File

@ -133,12 +133,13 @@ probe() {
} }
probe_need() { probe_need() {
local V=$1
probe $* probe $*
local V=$1
shift
eval VV=\$$V eval VV=\$$V
if [ -z "$VV" ] if [ -z "$VV" ]
then then
err "needed, but unable to find any of: $*" err "$V needed, but unable to find any of: $*"
fi fi
} }
@ -593,12 +594,13 @@ opt docs 1 "build standard library documentation"
opt compiler-docs 0 "build compiler documentation" opt compiler-docs 0 "build compiler documentation"
opt optimize-tests 1 "build tests with optimizations" opt optimize-tests 1 "build tests with optimizations"
opt debuginfo-tests 0 "build tests with debugger metadata" opt debuginfo-tests 0 "build tests with debugger metadata"
opt libcpp 1 "build with llvm with libc++ instead of libstdc++ when using clang" opt libcpp 1 "build llvm with libc++ instead of libstdc++ when using clang"
opt llvm-assertions 0 "build LLVM with assertions" opt llvm-assertions 0 "build LLVM with assertions"
opt debug-assertions 0 "build with debugging assertions" opt debug-assertions 0 "build with debugging assertions"
opt fast-make 0 "use .gitmodules as timestamp for submodule deps" opt fast-make 0 "use .gitmodules as timestamp for submodule deps"
opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds" opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
opt local-rust 0 "use an installed rustc rather than downloading a snapshot" opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
opt local-rebuild 0 "use an installed rustc matching the current version, for rebuilds"
opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM" opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
opt rpath 1 "build rpaths into rustc itself" opt rpath 1 "build rpaths into rustc itself"
opt stage0-landing-pads 1 "enable landing pads during bootstrap with stage0" opt stage0-landing-pads 1 "enable landing pads during bootstrap with stage0"
@ -724,7 +726,7 @@ if [ -n "$CFG_ENABLE_ORBIT" ]; then putvar CFG_ENABLE_ORBIT; fi
step_msg "looking for build programs" step_msg "looking for build programs"
probe_need CFG_CURLORWGET curl wget probe_need CFG_CURL curl
if [ -z "$CFG_PYTHON_PROVIDED" ]; then if [ -z "$CFG_PYTHON_PROVIDED" ]; then
probe_need CFG_PYTHON python2.7 python2 python probe_need CFG_PYTHON python2.7 python2 python
fi fi
@ -773,6 +775,9 @@ probe CFG_BISON bison
probe CFG_GDB gdb probe CFG_GDB gdb
probe CFG_LLDB lldb probe CFG_LLDB lldb
# For building LLVM
probe_need CFG_CMAKE cmake
# On MacOS X, invoking `javac` pops up a dialog if the JDK is not # On MacOS X, invoking `javac` pops up a dialog if the JDK is not
# installed. Since `javac` is only used if `antlr4` is available, # installed. Since `javac` is only used if `antlr4` is available,
# probe for it only in this case. # probe for it only in this case.
@ -847,6 +852,16 @@ then
BIN_SUF=.exe BIN_SUF=.exe
fi fi
# --enable-local-rebuild implies --enable-local-rust too
if [ -n "$CFG_ENABLE_LOCAL_REBUILD" ]
then
if [ -z "$CFG_ENABLE_LOCAL_RUST" ]
then
CFG_ENABLE_LOCAL_RUST=1
putvar CFG_ENABLE_LOCAL_RUST
fi
fi
if [ -n "$CFG_ENABLE_LOCAL_RUST" ] if [ -n "$CFG_ENABLE_LOCAL_RUST" ]
then then
system_rustc=$(which rustc) system_rustc=$(which rustc)
@ -976,11 +991,11 @@ then
LLVM_VERSION=$($LLVM_CONFIG --version) LLVM_VERSION=$($LLVM_CONFIG --version)
case $LLVM_VERSION in case $LLVM_VERSION in
(3.[6-8]*) (3.[7-8]*)
msg "found ok version of LLVM: $LLVM_VERSION" msg "found ok version of LLVM: $LLVM_VERSION"
;; ;;
(*) (*)
err "bad LLVM version: $LLVM_VERSION, need >=3.6" err "bad LLVM version: $LLVM_VERSION, need >=3.7"
;; ;;
esac esac
fi fi
@ -1163,36 +1178,6 @@ do
;; ;;
*-msvc) *-msvc)
# There are some MSYS python builds which will auto-translate
# windows-style paths to MSYS-style paths in Python itself.
# Unfortunately this breaks LLVM's build system as somewhere along
# the line LLVM prints a path into a file from Python and then CMake
# later tries to interpret that path. If Python prints a MSYS path
# and CMake tries to use it as a Windows path, you're gonna have a
# Bad Time.
#
# Consequently here we try to detect when that happens and print an
# error if it does.
if $CFG_PYTHON -c 'import sys; print sys.argv[1]' `pwd` | grep '^/' > /dev/null
then
err "
python is silently translating windows paths to MSYS paths \
and the build will fail if this python is used.
Either an official python install must be used or an \
alternative python package in MinGW must be used.
If you are building under msys2 try installing the mingw-w64-x86_64-python2 \
package instead of python2:
$ pacman -R python2 && pacman -S mingw-w64-x86_64-python2
"
fi
# MSVC requires cmake because that's how we're going to build LLVM
probe_need CFG_CMAKE cmake
# There are three builds of cmake on windows: MSVC, MinGW and Cygwin # There are three builds of cmake on windows: MSVC, MinGW and Cygwin
# The Cygwin build does not have generators for Visual Studio, so # The Cygwin build does not have generators for Visual Studio, so
# detect that here and error. # detect that here and error.
@ -1276,6 +1261,36 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
esac esac
done done
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ] || [ "$CFG_OSTYPE" = "pc-windows-msvc" ]
then
# There are some MSYS python builds which will auto-translate
# windows-style paths to MSYS-style paths in Python itself.
# Unfortunately this breaks LLVM's build system as somewhere along
# the line LLVM prints a path into a file from Python and then CMake
# later tries to interpret that path. If Python prints a MSYS path
# and CMake tries to use it as a Windows path, you're gonna have a
# Bad Time.
#
# Consequently here we try to detect when that happens and print an
# error if it does.
if $CFG_PYTHON -c 'import sys; print sys.argv[1]' `pwd` | grep '^/' > /dev/null
then
err "
python is silently translating windows paths to MSYS paths \
and the build will fail if this python is used.
Either an official python install must be used or an \
alternative python package in MinGW must be used.
If you are building under msys2 try installing the mingw-w64-x86_64-python2 \
package instead of python2:
$ pacman -S mingw-w64-x86_64-python2
"
fi
fi
if [ -n "$CFG_PERF" ] if [ -n "$CFG_PERF" ]
then then
HAVE_PERF_LOGFD=`$CFG_PERF stat --log-fd 2>&1 | grep 'unknown option'` HAVE_PERF_LOGFD=`$CFG_PERF stat --log-fd 2>&1 | grep 'unknown option'`
@ -1465,27 +1480,16 @@ do
elif [ -z $CFG_LLVM_ROOT ] elif [ -z $CFG_LLVM_ROOT ]
then then
LLVM_BUILD_DIR=${CFG_BUILD_DIR}$t/llvm LLVM_BUILD_DIR=${CFG_BUILD_DIR}$t/llvm
if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ] LLVM_INST_DIR=$LLVM_BUILD_DIR
then # For some crazy reason the MSVC output dir is different than Unix
LLVM_DBG_OPTS="--enable-debug-symbols --disable-optimized" if [ ${is_msvc} -ne 0 ]; then
# Just use LLVM straight from its build directory to if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ]
# avoid 'make install' time then
LLVM_INST_DIR=$LLVM_BUILD_DIR/Debug # Just use LLVM straight from its build directory to
else # avoid 'make install' time
LLVM_DBG_OPTS="--enable-optimized" LLVM_INST_DIR=$LLVM_BUILD_DIR/Debug
LLVM_INST_DIR=$LLVM_BUILD_DIR/Release else
fi LLVM_INST_DIR=$LLVM_BUILD_DIR/Release
if [ -z "$CFG_ENABLE_LLVM_ASSERTIONS" ]
then
LLVM_ASSERTION_OPTS="--disable-assertions"
else
LLVM_ASSERTION_OPTS="--enable-assertions"
# Apparently even if we request assertions be enabled for MSVC,
# LLVM's CMake build system ignore this and outputs in `Release`
# anyway.
if [ ${is_msvc} -eq 0 ]; then
LLVM_INST_DIR=${LLVM_INST_DIR}+Asserts
fi fi
fi fi
else else
@ -1543,88 +1547,60 @@ do
err "can only build LLVM for x86 platforms" err "can only build LLVM for x86 platforms"
;; ;;
esac esac
CFG_CMAKE_GENERATOR=$generator else
putvar CFG_CMAKE_GENERATOR generator="Unix Makefiles"
fi fi
CFG_CMAKE_GENERATOR=$generator
putvar CFG_CMAKE_GENERATOR
if [ ${do_reconfigure} -ne 0 ] && [ ${is_msvc} -ne 0 ] msg "configuring LLVM for $t"
then
msg "configuring LLVM for $t with cmake"
CMAKE_ARGS="-DLLVM_INCLUDE_TESTS=OFF" LLVM_CFLAGS_32=""
if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ]; then LLVM_CXXFLAGS_32=""
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_BUILD_TYPE=Debug" LLVM_LDFLAGS_32=""
else LLVM_CFLAGS_64=""
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release" LLVM_CXXFLAGS_64=""
fi LLVM_LDFLAGS_64=""
if [ -z "$CFG_ENABLE_LLVM_ASSERTIONS" ]
then
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_ASSERTIONS=OFF"
else
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_ASSERTIONS=ON"
fi
msg "configuring LLVM with:" case "$CFG_CC" in
msg "$CMAKE_ARGS" ("ccache clang")
LLVM_CXX_32="ccache"
LLVM_CC_32="ccache"
LLVM_CXX_32_ARG1="clang++"
LLVM_CC_32_ARG1="clang"
LLVM_CFLAGS_32="-Qunused-arguments"
LLVM_CXXFLAGS_32="-Qunused-arguments"
(cd $LLVM_BUILD_DIR && "$CFG_CMAKE" $CFG_LLVM_SRC_DIR \ LLVM_CXX_64="ccache"
-G "$CFG_CMAKE_GENERATOR" \ LLVM_CC_64="ccache"
$CMAKE_ARGS) LLVM_CXX_64_ARG1="clang++"
need_ok "LLVM cmake configure failed" LLVM_CC_64_ARG1="clang"
fi LLVM_CFLAGS_64="-Qunused-arguments"
LLVM_CXXFLAGS_64="-Qunused-arguments"
if [ ${do_reconfigure} -ne 0 ] && [ ${is_msvc} -eq 0 ]
then
# LLVM's configure doesn't recognize the new Windows triples yet
gnu_t=$(to_gnu_triple $t)
msg "configuring LLVM for $gnu_t"
LLVM_TARGETS="--enable-targets=x86,x86_64,arm,aarch64,mips,powerpc"
LLVM_BUILD="--build=$gnu_t"
LLVM_HOST="--host=$gnu_t"
LLVM_TARGET="--target=$gnu_t"
# Disable unused LLVM features
LLVM_OPTS="$LLVM_DBG_OPTS $LLVM_ASSERTION_OPTS --disable-docs --enable-bindings=none"
# Disable term-info, linkage of which comes in multiple forms,
# making our snapshots incompatible (#9334)
LLVM_OPTS="$LLVM_OPTS --disable-terminfo"
# Try to have LLVM pull in as few dependencies as possible (#9397)
LLVM_OPTS="$LLVM_OPTS --disable-zlib --disable-libffi"
# Use win32 native thread/lock apis instead of pthread wrapper.
# (llvm's configure tries to find pthread first, so we have to disable it explicitly.)
# Also note that pthreads works badly on mingw-w64 systems: #8996
case "$CFG_BUILD" in
(*-windows-gnu)
LLVM_OPTS="$LLVM_OPTS --disable-pthreads"
;; ;;
esac ("clang")
LLVM_CXX_32="clang++"
LLVM_CC_32="clang"
LLVM_CFLAGS_32="-Qunused-arguments"
LLVM_CXXFLAGS_32="-Qunused-arguments"
case "$CFG_CC" in LLVM_CXX_64="clang++"
("ccache clang") LLVM_CC_64="clang"
LLVM_CXX_32="ccache clang++ -Qunused-arguments" LLVM_CFLAGS_64="-Qunused-arguments"
LLVM_CC_32="ccache clang -Qunused-arguments" LLVM_CXXFLAGS_64="-Qunused-arguments"
LLVM_CXX_64="ccache clang++ -Qunused-arguments"
LLVM_CC_64="ccache clang -Qunused-arguments"
;; ;;
("clang") ("ccache gcc")
LLVM_CXX_32="clang++ -Qunused-arguments" LLVM_CXX_32="ccache"
LLVM_CC_32="clang -Qunused-arguments" LLVM_CC_32="ccache"
LLVM_CXX_32_ARG1="clang++"
LLVM_CC_32_ARG1="clang"
LLVM_CXX_64="clang++ -Qunused-arguments" LLVM_CXX_64="ccache"
LLVM_CC_64="clang -Qunused-arguments" LLVM_CC_64="ccache"
LLVM_CXX_64_ARG1="g++"
LLVM_CC_64_ARG1="gcc"
;; ;;
("ccache gcc") ("gcc")
LLVM_CXX_32="ccache g++"
LLVM_CC_32="ccache gcc"
LLVM_CXX_64="ccache g++"
LLVM_CC_64="ccache gcc"
;;
("gcc")
LLVM_CXX_32="g++" LLVM_CXX_32="g++"
LLVM_CC_32="gcc" LLVM_CC_32="gcc"
@ -1632,7 +1608,7 @@ do
LLVM_CC_64="gcc" LLVM_CC_64="gcc"
;; ;;
(*) (*)
msg "inferring LLVM_CXX/CC from CXX/CC = $CXX/$CC" msg "inferring LLVM_CXX/CC from CXX/CC = $CXX/$CC"
if [ -n "$CFG_ENABLE_CCACHE" ] if [ -n "$CFG_ENABLE_CCACHE" ]
then then
@ -1641,11 +1617,15 @@ do
err "ccache requested but not found" err "ccache requested but not found"
fi fi
LLVM_CXX_32="ccache $CXX" LLVM_CXX_32="ccache"
LLVM_CC_32="ccache $CC" LLVM_CC_32="ccache"
LLVM_CXX_32_ARG1="$CXX"
LLVM_CC_32_ARG1="$CC"
LLVM_CXX_64="ccache $CXX" LLVM_CXX_64="ccache"
LLVM_CC_64="ccache $CC" LLVM_CC_64="ccache"
LLVM_CXX_64_ARG1="$CXX"
LLVM_CC_64_ARG1="$CC"
else else
LLVM_CXX_32="$CXX" LLVM_CXX_32="$CXX"
LLVM_CC_32="$CC" LLVM_CC_32="$CC"
@ -1655,86 +1635,102 @@ do
fi fi
;; ;;
esac esac
case "$CFG_CPUTYPE" in case "$CFG_CPUTYPE" in
(x86*) (x86*)
LLVM_CXX_32="$LLVM_CXX_32 -m32" LLVM_CFLAGS_32="$LLVM_CFLAGS_32 -m32"
LLVM_CC_32="$LLVM_CC_32 -m32" LLVM_CXXFLAGS_32="$LLVM_CXXFLAGS_32 -m32"
LLVM_LDFLAGS_32="$LLVM_LDFLAGS_32 -m32"
;;
esac
LLVM_CFLAGS_32="-m32" if echo $t | grep -q x86_64
LLVM_CXXFLAGS_32="-m32" then
LLVM_LDFLAGS_32="-m32" LLVM_CXX=$LLVM_CXX_64
LLVM_CC=$LLVM_CC_64
LLVM_CXX_ARG1=$LLVM_CXX_64_ARG1
LLVM_CC_ARG1=$LLVM_CC_64_ARG1
LLVM_CFLAGS=$LLVM_CFLAGS_64
LLVM_CXXFLAGS=$LLVM_CXXFLAGS_64
LLVM_LDFLAGS=$LLVM_LDFLAGS_64
else
LLVM_CXX=$LLVM_CXX_32
LLVM_CC=$LLVM_CC_32
LLVM_CXX_ARG1=$LLVM_CXX_32_ARG1
LLVM_CC_ARG1=$LLVM_CC_32_ARG1
LLVM_CFLAGS=$LLVM_CFLAGS_32
LLVM_CXXFLAGS=$LLVM_CXXFLAGS_32
LLVM_LDFLAGS=$LLVM_LDFLAGS_32
fi
LLVM_CFLAGS_64="" if [ "$CFG_USING_LIBCPP" != "0" ]; then
LLVM_CXXFLAGS_64="" CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_LIBCXX=ON"
LLVM_LDFLAGS_64="" fi
LLVM_CXX_32="$LLVM_CXX_32 -m32" # Turn off things we don't need
LLVM_CC_32="$LLVM_CC_32 -m32" CMAKE_ARGS="$CMAKE_ARGS -DLLVM_INCLUDE_TESTS=OFF"
;; CMAKE_ARGS="$CMAKE_ARGS -DLLVM_INCLUDE_EXAMPLES=OFF"
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_INCLUDE_DOCS=OFF"
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_ZLIB=OFF"
CMAKE_ARGS="$CMAKE_ARGS -DWITH_POLY=OFF"
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_TERMINFO=OFF"
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_LIBEDIT=OFF"
(*) arch="$(echo "$t" | cut -d - -f 1)"
LLVM_CFLAGS_32=""
LLVM_CXXFLAGS_32=""
LLVM_LDFLAGS_32=""
LLVM_CFLAGS_64="" if [ "$arch" = i686 ]; then
LLVM_CXXFLAGS_64="" CMAKE_ARGS="$CMAKE_ARGS -DLLVM_BUILD_32_BITS=ON"
LLVM_LDFLAGS_64="" fi
;;
esac
if echo $t | grep -q x86_64 if [ "$t" != "$CFG_BUILD" ]; then
then # see http://llvm.org/docs/HowToCrossCompileLLVM.html
LLVM_CXX=$LLVM_CXX_64 CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CROSSCOMPILING=True"
LLVM_CC=$LLVM_CC_64 CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TARGET_ARCH=$arch"
LLVM_CFLAGS=$LLVM_CFLAGS_64 CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TABLEGEN=$CFG_BUILD_DIR/$CFG_BUILD/llvm/bin/llvm-tblgen"
LLVM_CXXFLAGS=$LLVM_CXXFLAGS_64 CMAKE_ARGS="$CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=$t"
LLVM_LDFLAGS=$LLVM_LDFLAGS_64 fi
else
LLVM_CXX=$LLVM_CXX_32 # MSVC handles compiler business itself
LLVM_CC=$LLVM_CC_32 if [ ${is_msvc} -eq 0 ]; then
LLVM_CFLAGS=$LLVM_CFLAGS_32 CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_C_COMPILER=$LLVM_CC"
LLVM_CXXFLAGS=$LLVM_CXXFLAGS_32 CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CXX_COMPILER=$LLVM_CXX"
LLVM_LDFLAGS=$LLVM_LDFLAGS_32 CMAKE_ARGS="$CMAKE_ARGS '-DCMAKE_C_FLAGS=$LLVM_CFLAGS'"
CMAKE_ARGS="$CMAKE_ARGS '-DCMAKE_CXX_FLAGS=$LLVM_CXXFLAGS'"
if [ -n "$LLVM_CC_ARG1" ]; then
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_C_COMPILER_ARG1=$LLVM_CC_ARG1"
fi fi
if [ -n "$LLVM_CXX_ARG1" ]; then
CXX=$LLVM_CXX CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CXX_COMPILER_ARG1=$LLVM_CXX_ARG1"
CC=$LLVM_CC
CFLAGS="$CFLAGS $LLVM_CFLAGS"
CXXFLAGS="$CXXFLAGS $LLVM_CXXFLAGS"
LDFLAGS="$LDFLAGS $LLVM_LDFLAGS"
if [ "$CFG_USING_LIBCPP" != "0" ]; then
LLVM_OPTS="$LLVM_OPTS --enable-libcpp"
fi fi
# FIXME: What about LDFLAGS?
fi
LLVM_FLAGS="$LLVM_TARGETS $LLVM_OPTS $LLVM_BUILD \ if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ]; then
$LLVM_HOST $LLVM_TARGET --with-python=$CFG_PYTHON" CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_BUILD_TYPE=Debug"
else
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release"
fi
if [ -z "$CFG_ENABLE_LLVM_ASSERTIONS" ]
then
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_ASSERTIONS=OFF"
else
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_ASSERTIONS=ON"
fi
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TARGETS_TO_BUILD='X86;ARM;AArch64;Mips;PowerPC'"
CMAKE_ARGS="$CMAKE_ARGS -G '$CFG_CMAKE_GENERATOR'"
CMAKE_ARGS="$CMAKE_ARGS $CFG_LLVM_SRC_DIR"
if [ ${do_reconfigure} -ne 0 ]
then
msg "configuring LLVM for $t with cmake"
msg "configuring LLVM with:" msg "configuring LLVM with:"
msg "$LLVM_FLAGS" msg "$CMAKE_ARGS"
export CXX (cd $LLVM_BUILD_DIR && eval "\"$CFG_CMAKE\"" $CMAKE_ARGS)
export CC need_ok "LLVM cmake configure failed"
export CFLAGS
export CXXFLAGS
export LDFLAGS
cd $LLVM_BUILD_DIR
case $CFG_SRC_DIR in
/* | [a-z]:* | [A-Z]:*)
${CFG_LLVM_SRC_DIR}configure $LLVM_FLAGS
;;
*)
${CFG_BUILD_DIR}${CFG_LLVM_SRC_DIR}configure \
$LLVM_FLAGS
;;
esac
need_ok "LLVM configure failed"
cd $CFG_BUILD_DIR
fi fi
# Construct variables for LLVM build and install directories for # Construct variables for LLVM build and install directories for

View File

@ -8,7 +8,7 @@ CFG_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS) CFG_JEMALLOC_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS) CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS) -march=i686
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS) CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32 CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list= CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=

View File

@ -1,6 +1,6 @@
# i686-unknown-linux-musl configuration # i686-unknown-linux-musl configuration
CC_i686-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc CC_i686-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc
CXX_i686-unknown-linux-musl=notaprogram CXX_i686-unknown-linux-musl=$(CXX)
CPP_i686-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc -E CPP_i686-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc -E
AR_i686-unknown-linux-musl=$(AR) AR_i686-unknown-linux-musl=$(AR)
CFG_INSTALL_ONLY_RLIB_i686-unknown-linux-musl = 1 CFG_INSTALL_ONLY_RLIB_i686-unknown-linux-musl = 1

View File

@ -7,10 +7,10 @@ CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_mips-unknown-linux-gnu=lib$(1).a CFG_STATIC_LIB_NAME_mips-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_mips-unknown-linux-gnu := -mips32r2 -msoft-float -mabi=32 $(CFLAGS) CFG_JEMALLOC_CFLAGS_mips-unknown-linux-gnu := -mips32r2 -mabi=32 $(CFLAGS)
CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32 $(CFLAGS) CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -mabi=32 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti $(CXXFLAGS) CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32 CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -mabi=32
CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list= CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_mips-unknown-linux-gnu := CFG_LLC_FLAGS_mips-unknown-linux-gnu :=
CFG_INSTALL_NAME_mips-unknown-linux-gnu = CFG_INSTALL_NAME_mips-unknown-linux-gnu =

View File

@ -1,6 +1,6 @@
# x86_64-unknown-linux-musl configuration # x86_64-unknown-linux-musl configuration
CC_x86_64-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc CC_x86_64-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc
CXX_x86_64-unknown-linux-musl=notaprogram CXX_x86_64-unknown-linux-musl=$(CXX)
CPP_x86_64-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc -E CPP_x86_64-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc -E
AR_x86_64-unknown-linux-musl=$(AR) AR_x86_64-unknown-linux-musl=$(AR)
CFG_INSTALL_ONLY_RLIB_x86_64-unknown-linux-musl = 1 CFG_INSTALL_ONLY_RLIB_x86_64-unknown-linux-musl = 1

View File

@ -57,10 +57,10 @@ TARGET_CRATES := libc std term \
panic_abort panic_unwind unwind panic_abort panic_unwind unwind
RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_driver \ RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_driver \
rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint \ rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint \
rustc_data_structures rustc_platform_intrinsics \ rustc_data_structures rustc_platform_intrinsics rustc_errors \
rustc_plugin rustc_metadata rustc_passes rustc_save_analysis \ rustc_plugin rustc_metadata rustc_passes rustc_save_analysis \
rustc_const_eval rustc_const_math rustc_incremental rustc_const_eval rustc_const_math rustc_incremental
HOST_CRATES := syntax syntax_ext $(RUSTC_CRATES) rustdoc fmt_macros \ HOST_CRATES := syntax syntax_ext syntax_pos $(RUSTC_CRATES) rustdoc fmt_macros \
flate arena graphviz rbml log serialize flate arena graphviz rbml log serialize
TOOLS := compiletest rustdoc rustc rustbook error_index_generator TOOLS := compiletest rustdoc rustc rustbook error_index_generator
@ -98,43 +98,45 @@ DEPS_serialize := std log
DEPS_term := std DEPS_term := std
DEPS_test := std getopts term native:rust_test_helpers DEPS_test := std getopts term native:rust_test_helpers
DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos
DEPS_syntax_ext := syntax fmt_macros DEPS_syntax_ext := syntax syntax_pos rustc_errors fmt_macros
DEPS_syntax_pos := serialize
DEPS_rustc_const_math := std syntax log serialize DEPS_rustc_const_math := std syntax log serialize
DEPS_rustc_const_eval := rustc_const_math rustc syntax log serialize \ DEPS_rustc_const_eval := rustc_const_math rustc syntax log serialize \
rustc_back graphviz rustc_back graphviz syntax_pos
DEPS_rustc := syntax fmt_macros flate arena serialize getopts rbml \ DEPS_rustc := syntax fmt_macros flate arena serialize getopts rbml \
log graphviz rustc_llvm rustc_back rustc_data_structures\ log graphviz rustc_llvm rustc_back rustc_data_structures\
rustc_const_math rustc_const_math syntax_pos rustc_errors
DEPS_rustc_back := std syntax flate log libc DEPS_rustc_back := std syntax flate log libc
DEPS_rustc_borrowck := rustc rustc_mir log graphviz syntax DEPS_rustc_borrowck := rustc log graphviz syntax syntax_pos rustc_errors rustc_mir
DEPS_rustc_data_structures := std log serialize DEPS_rustc_data_structures := std log serialize
DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \ DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
rustc_typeck rustc_mir rustc_resolve log syntax serialize rustc_llvm \ rustc_typeck rustc_mir rustc_resolve log syntax serialize rustc_llvm \
rustc_trans rustc_privacy rustc_lint rustc_plugin \ rustc_trans rustc_privacy rustc_lint rustc_plugin \
rustc_metadata syntax_ext rustc_passes rustc_save_analysis rustc_const_eval \ rustc_metadata syntax_ext rustc_passes rustc_save_analysis rustc_const_eval \
rustc_incremental rustc_incremental syntax_pos rustc_errors
DEPS_rustc_lint := rustc log syntax rustc_const_eval DEPS_rustc_errors := log libc serialize syntax_pos
DEPS_rustc_lint := rustc log syntax syntax_pos rustc_const_eval
DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
DEPS_rustc_metadata := rustc syntax rbml rustc_const_math DEPS_rustc_metadata := rustc syntax syntax_pos rustc_errors rbml rustc_const_math
DEPS_rustc_passes := syntax rustc core rustc_const_eval DEPS_rustc_passes := syntax syntax_pos rustc core rustc_const_eval rustc_errors
DEPS_rustc_mir := rustc syntax rustc_const_math rustc_const_eval rustc_bitflags DEPS_rustc_mir := rustc syntax syntax_pos rustc_const_math rustc_const_eval rustc_bitflags
DEPS_rustc_resolve := arena rustc log syntax DEPS_rustc_resolve := arena rustc log syntax syntax_pos rustc_errors
DEPS_rustc_platform_intrinsics := std DEPS_rustc_platform_intrinsics := std
DEPS_rustc_plugin := rustc rustc_metadata syntax rustc_mir DEPS_rustc_plugin := rustc rustc_metadata syntax syntax_pos rustc_errors
DEPS_rustc_privacy := rustc log syntax DEPS_rustc_privacy := rustc log syntax syntax_pos
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back rustc_mir \ DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
log syntax serialize rustc_llvm rustc_platform_intrinsics \ log syntax serialize rustc_llvm rustc_platform_intrinsics \
rustc_const_math rustc_const_eval rustc_incremental rustc_const_math rustc_const_eval rustc_incremental rustc_errors syntax_pos
DEPS_rustc_incremental := rbml rustc serialize rustc_data_structures DEPS_rustc_incremental := rbml rustc syntax_pos serialize rustc_data_structures
DEPS_rustc_save_analysis := rustc log syntax serialize DEPS_rustc_save_analysis := rustc log syntax syntax_pos serialize
DEPS_rustc_typeck := rustc syntax rustc_platform_intrinsics rustc_const_math \ DEPS_rustc_typeck := rustc syntax syntax_pos rustc_platform_intrinsics rustc_const_math \
rustc_const_eval rustc_const_eval rustc_errors
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \ DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
test rustc_lint rustc_const_eval test rustc_lint rustc_const_eval syntax_pos
TOOL_DEPS_compiletest := test getopts log serialize TOOL_DEPS_compiletest := test getopts log serialize

View File

@ -27,31 +27,36 @@ endif
define DEF_LLVM_RULES define DEF_LLVM_RULES
ifeq ($(1),$$(CFG_BUILD))
LLVM_DEPS_TARGET_$(1) := $$(LLVM_DEPS)
else
LLVM_DEPS_TARGET_$(1) := $$(LLVM_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
endif
# If CFG_LLVM_ROOT is defined then we don't build LLVM ourselves # If CFG_LLVM_ROOT is defined then we don't build LLVM ourselves
ifeq ($(CFG_LLVM_ROOT),) ifeq ($(CFG_LLVM_ROOT),)
LLVM_STAMP_$(1) = $$(CFG_LLVM_BUILD_DIR_$(1))/llvm-auto-clean-stamp LLVM_STAMP_$(1) = $$(CFG_LLVM_BUILD_DIR_$(1))/llvm-auto-clean-stamp
LLVM_DONE_$(1) = $$(CFG_LLVM_BUILD_DIR_$(1))/llvm-finished-building
ifeq ($$(findstring msvc,$(1)),msvc) $$(LLVM_CONFIG_$(1)): $$(LLVM_DONE_$(1))
$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS) $$(LLVM_STAMP_$(1)) $$(LLVM_DONE_$(1)): $$(LLVM_DEPS_TARGET_$(1)) $$(LLVM_STAMP_$(1))
@$$(call E, cmake: llvm) @$$(call E, cmake: llvm)
ifeq ($$(findstring msvc,$(1)),msvc)
$$(Q)$$(CFG_CMAKE) --build $$(CFG_LLVM_BUILD_DIR_$(1)) \ $$(Q)$$(CFG_CMAKE) --build $$(CFG_LLVM_BUILD_DIR_$(1)) \
--config $$(LLVM_BUILD_CONFIG_MODE) --config $$(LLVM_BUILD_CONFIG_MODE)
$$(Q)touch $$(LLVM_CONFIG_$(1))
clean-llvm$(1):
else else
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1))
endif
$$(Q)touch $$@
$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS) $$(LLVM_STAMP_$(1)) ifeq ($$(findstring msvc,$(1)),msvc)
@$$(call E, make: llvm)
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) $$(CFG_LLVM_BUILD_ENV_$(1)) ONLY_TOOLS="$$(LLVM_TOOLS)"
$$(Q)touch $$(LLVM_CONFIG_$(1))
clean-llvm$(1): clean-llvm$(1):
else
clean-llvm$(1):
@$$(call E, clean: llvm)
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) clean $$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) clean
endif endif
else else

View File

@ -13,12 +13,12 @@
###################################################################### ######################################################################
# The version number # The version number
CFG_RELEASE_NUM=1.10.0 CFG_RELEASE_NUM=1.11.0
# An optional number to put after the label, e.g. '.2' -> '-beta.2' # An optional number to put after the label, e.g. '.2' -> '-beta.2'
# NB Make sure it starts with a dot to conform to semver pre-release # NB Make sure it starts with a dot to conform to semver pre-release
# versions (section 9) # versions (section 9)
CFG_PRERELEASE_VERSION=.4 CFG_PRERELEASE_VERSION=.3
# Append a version-dependent hash to each library, so we can install different # Append a version-dependent hash to each library, so we can install different
# versions in the same place # versions in the same place
@ -34,7 +34,14 @@ CFG_FILENAME_EXTRA=$(shell printf '%s' $(CFG_RELEASE)$(CFG_EXTRA_FILENAME) | $(C
# intentionally not "secure" by any definition, this is largely just a deterrent # intentionally not "secure" by any definition, this is largely just a deterrent
# from users enabling unstable features on the stable compiler. # from users enabling unstable features on the stable compiler.
CFG_BOOTSTRAP_KEY=$(CFG_FILENAME_EXTRA) CFG_BOOTSTRAP_KEY=$(CFG_FILENAME_EXTRA)
# The stage0 compiler needs to use the previous key recorded in src/stage0.txt,
# except for local-rebuild when it just uses the same current key.
ifdef CFG_ENABLE_LOCAL_REBUILD
CFG_BOOTSTRAP_KEY_STAGE0=$(CFG_BOOTSTRAP_KEY)
else
CFG_BOOTSTRAP_KEY_STAGE0=$(shell grep 'rustc_key' $(S)src/stage0.txt | sed 's/rustc_key: '//) CFG_BOOTSTRAP_KEY_STAGE0=$(shell grep 'rustc_key' $(S)src/stage0.txt | sed 's/rustc_key: '//)
endif
ifeq ($(CFG_RELEASE_CHANNEL),stable) ifeq ($(CFG_RELEASE_CHANNEL),stable)
# This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly" # This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly"
@ -152,7 +159,7 @@ ifdef CFG_ENABLE_ORBIT
endif endif
ifdef SAVE_TEMPS ifdef SAVE_TEMPS
CFG_RUSTC_FLAGS += --save-temps CFG_RUSTC_FLAGS += -C save-temps
endif endif
ifdef ASM_COMMENTS ifdef ASM_COMMENTS
CFG_RUSTC_FLAGS += -Z asm-comments CFG_RUSTC_FLAGS += -Z asm-comments
@ -526,6 +533,11 @@ ifneq ($(strip $(CFG_BUILD)),$(strip $(3)))
CFGFLAG$(1)_T_$(2)_H_$(3) = stage1 CFGFLAG$(1)_T_$(2)_H_$(3) = stage1
RPATH_VAR$(1)_T_$(2)_H_$(3) := $$(TARGET_RPATH_VAR1_T_$(2)_H_$$(CFG_BUILD)) RPATH_VAR$(1)_T_$(2)_H_$(3) := $$(TARGET_RPATH_VAR1_T_$(2)_H_$$(CFG_BUILD))
else
ifdef CFG_ENABLE_LOCAL_REBUILD
# Assume the local-rebuild rustc already has stage1 features too.
CFGFLAG$(1)_T_$(2)_H_$(3) = stage1
endif
endif endif
endif endif

159
mk/rt.mk
View File

@ -233,35 +233,98 @@ COMPRT_DEPS := $(wildcard \
$(S)src/compiler-rt/*/*/*/*) $(S)src/compiler-rt/*/*/*/*)
endif endif
# compiler-rt's build system is a godawful mess. Here we figure out
# the ridiculous platform-specific values and paths necessary to get
# useful artifacts out of it.
COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt) COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1)) COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
ifeq ($$(findstring msvc,$(1)),msvc) COMPRT_ARCH_$(1) := $$(word 1,$$(subst -, ,$(1)))
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
@$$(call E, cmake: compiler-rt) # All this is to figure out the path to the compiler-rt bin
$$(Q)cd "$$(COMPRT_BUILD_DIR_$(1))"; $$(CFG_CMAKE) "$(S)src/compiler-rt" \ ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
-DCMAKE_BUILD_TYPE=$$(LLVM_BUILD_CONFIG_MODE) \ COMPRT_DIR_$(1) := windows/Release
-DLLVM_CONFIG_PATH=$$(LLVM_CONFIG_$$(CFG_BUILD)) \ COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(patsubst i%86,i386,$$(COMPRT_ARCH_$(1)))
-G"$$(CFG_CMAKE_GENERATOR)" endif
$$(Q)$$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \
--target lib/builtins/builtins \ ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
--config $$(LLVM_BUILD_CONFIG_MODE) \ COMPRT_DIR_$(1) := windows
-- //v:m //nologo COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
$$(Q)cp $$(COMPRT_BUILD_DIR_$(1))/lib/windows/$$(LLVM_BUILD_CONFIG_MODE)/clang_rt.builtins-$$(HOST_$(1)).lib $$@ endif
else
COMPRT_CC_$(1) := $$(CC_$(1)) ifeq ($$(findstring darwin,$(1)),darwin)
COMPRT_AR_$(1) := $$(AR_$(1)) COMPRT_DIR_$(1) := builtins
# We chomp -Werror here because GCC warns about the type signature of COMPRT_LIB_NAME_$(1) := clang_rt.builtins_$$(patsubst i686,i386,$$(COMPRT_ARCH_$(1)))_osx
# builtins not matching its own and the build fails. It's a bit hacky, endif
# but what can we do, we're building libclang-rt using GCC ......
COMPRT_CFLAGS_$(1) := $$(CFG_GCCISH_CFLAGS_$(1)) -Wno-error -std=c99 ifeq ($$(findstring ios,$(1)),ios)
COMPRT_DIR_$(1) := builtins
COMPRT_ARCH_$(1) := $$(patsubst armv7s,armv7em,$$(COMPRT_ARCH_$(1)))
COMPRT_LIB_NAME_$(1) := clang_rt.hard_pic_$$(COMPRT_ARCH_$(1))_macho_embedded
ifeq ($$(COMPRT_ARCH_$(1)),aarch64)
COMPRT_LIB_NAME_$(1) := clang_rt.builtins_arm64_ios
endif
COMPRT_DEFINES_$(1) := -DCOMPILER_RT_ENABLE_IOS=ON
endif
ifndef COMPRT_DIR_$(1)
# NB: FreeBSD and NetBSD output to "linux"...
COMPRT_DIR_$(1) := linux
COMPRT_ARCH_$(1) := $$(patsubst i586,i386,$$(COMPRT_ARCH_$(1)))
ifeq ($$(findstring android,$(1)),android)
ifeq ($$(findstring arm,$$(COMPRT_ARCH_$(1))),arm)
COMPRT_ARCH_$(1) := armhf
endif
endif
ifeq ($$(findstring eabihf,$(1)),eabihf)
ifeq ($$(findstring armv7,$(1)),)
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-armhf
endif
endif
ifndef COMPRT_LIB_NAME_$(1)
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
endif
endif
ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
COMPRT_LIB_FILE_$(1) := lib$$(COMPRT_LIB_NAME_$(1)).a
endif
ifeq ($$(findstring android,$(1)),android)
ifeq ($$(findstring arm,$(1)),arm)
COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1))-android)
endif
endif
ifndef COMPRT_LIB_FILE_$(1)
COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1)))
endif
COMPRT_OUTPUT_$(1) := $$(COMPRT_BUILD_DIR_$(1))/lib/$$(COMPRT_DIR_$(1))/$$(COMPRT_LIB_FILE_$(1))
ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
COMPRT_BUILD_ARGS_$(1) := //v:m //nologo
COMPRT_BUILD_TARGET_$(1) := lib/builtins/builtins
COMPRT_BUILD_CC_$(1) :=
else
COMPRT_BUILD_ARGS_$(1) :=
ifndef COMPRT_BUILD_TARGET_$(1)
COMPRT_BUILD_TARGET_$(1) := $$(COMPRT_LIB_NAME_$(1))
endif
COMPRT_BUILD_CC_$(1) := -DCMAKE_C_COMPILER=$$(call FIND_COMPILER,$$(CC_$(1))) \
-DCMAKE_CXX_COMPILER=$$(call FIND_COMPILER,$$(CXX_$(1)))
ifeq ($$(findstring ios,$(1)),)
COMPRT_BUILD_CC_$(1) := $$(COMPRT_BUILD_CC_$(1)) \
-DCMAKE_C_FLAGS="$$(CFG_GCCISH_CFLAGS_$(1)) -Wno-error"
endif
# FreeBSD Clang's packaging is problematic; it doesn't copy unwind.h to
# the standard include directory. This should really be in our changes to
# compiler-rt, but we override the CFLAGS here so there isn't much choice
ifeq ($$(findstring freebsd,$(1)),freebsd)
COMPRT_CFLAGS_$(1) += -I/usr/include/c++/v1
endif endif
ifeq ($$(findstring emscripten,$(1)),emscripten) ifeq ($$(findstring emscripten,$(1)),emscripten)
@ -273,20 +336,26 @@ $$(COMPRT_LIB_$(1)):
else else
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
@$$(call E, make: compiler-rt) @$$(call E, cmake: compiler-rt)
$$(Q)$$(MAKE) -C "$(S)src/compiler-rt" \ $$(Q)rm -rf $$(COMPRT_BUILD_DIR_$(1))
ProjSrcRoot="$(S)src/compiler-rt" \ $$(Q)mkdir $$(COMPRT_BUILD_DIR_$(1))
ProjObjRoot="$$(abspath $$(COMPRT_BUILD_DIR_$(1)))" \ $$(Q)cd "$$(COMPRT_BUILD_DIR_$(1))"; \
CC='$$(COMPRT_CC_$(1))' \ $$(CFG_CMAKE) "$(S)src/compiler-rt" \
AR='$$(COMPRT_AR_$(1))' \ -DCMAKE_BUILD_TYPE=$$(LLVM_BUILD_CONFIG_MODE) \
RANLIB='$$(COMPRT_AR_$(1)) s' \ -DLLVM_CONFIG_PATH=$$(LLVM_CONFIG_$$(CFG_BUILD)) \
CFLAGS="$$(COMPRT_CFLAGS_$(1))" \ -DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=$(1) \
TargetTriple=$(1) \ -DCOMPILER_RT_BUILD_SANITIZERS=OFF \
triple-builtins -DCOMPILER_RT_BUILD_EMUTLS=OFF \
$$(Q)cp $$(COMPRT_BUILD_DIR_$(1))/triple/builtins/libcompiler_rt.a $$@ $$(COMPRT_DEFINES_$(1)) \
$$(COMPRT_BUILD_CC_$(1)) \
-G"$$(CFG_CMAKE_GENERATOR)"
$$(Q)$$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \
--target $$(COMPRT_BUILD_TARGET_$(1)) \
--config $$(LLVM_BUILD_CONFIG_MODE) \
-- $$(COMPRT_BUILD_ARGS_$(1)) $$(MFLAGS)
$$(Q)cp "$$(COMPRT_OUTPUT_$(1))" $$@
endif # if emscripten
endif endif
################################################################################ ################################################################################
@ -310,20 +379,15 @@ ifeq ($$(findstring darwin,$$(OSTYPE_$(1))),darwin)
$$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_LIB_$(1)):
touch $$@ touch $$@
else else ifeq ($$(findstring ios,$$(OSTYPE_$(1))),ios)
ifeq ($$(findstring ios,$$(OSTYPE_$(1))),ios)
# See comment above # See comment above
$$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_LIB_$(1)):
touch $$@ touch $$@
else else ifeq ($$(findstring msvc,$(1)),msvc)
ifeq ($$(findstring msvc,$(1)),msvc)
# See comment above # See comment above
$$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_LIB_$(1)):
touch $$@ touch $$@
else else ifeq ($$(findstring emscripten,$(1)),emscripten)
ifeq ($$(findstring emscripten,$(1)),emscripten)
# FIXME: libbacktrace doesn't understand the emscripten triple # FIXME: libbacktrace doesn't understand the emscripten triple
$$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_LIB_$(1)):
touch $$@ touch $$@
@ -376,10 +440,7 @@ $$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_BUILD_DIR_$(1))/Makefile $$(MKFILE_DEPS)
INCDIR=$(S)src/libbacktrace INCDIR=$(S)src/libbacktrace
$$(Q)cp $$(BACKTRACE_BUILD_DIR_$(1))/.libs/libbacktrace.a $$@ $$(Q)cp $$(BACKTRACE_BUILD_DIR_$(1))/.libs/libbacktrace.a $$@
endif # endif for emscripten endif
endif # endif for msvc
endif # endif for ios
endif # endif for darwin
################################################################################ ################################################################################
# libc/libunwind for musl # libc/libunwind for musl

View File

@ -276,6 +276,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
check-stage$(1)-T-$(2)-H-$(3)-incremental-exec \ check-stage$(1)-T-$(2)-H-$(3)-incremental-exec \
check-stage$(1)-T-$(2)-H-$(3)-ui-exec \ check-stage$(1)-T-$(2)-H-$(3)-ui-exec \
check-stage$(1)-T-$(2)-H-$(3)-doc-exec \ check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
check-stage$(1)-T-$(2)-H-$(3)-doc-error-index-exec \
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec check-stage$(1)-T-$(2)-H-$(3)-pretty-exec
ifndef CFG_DISABLE_CODEGEN_TESTS ifndef CFG_DISABLE_CODEGEN_TESTS

View File

@ -50,7 +50,7 @@ compiler. What actually happens when you invoke rustbuild is:
1. The entry point script, `src/bootstrap/bootstrap.py` is run. This script is 1. The entry point script, `src/bootstrap/bootstrap.py` is run. This script is
responsible for downloading the stage0 compiler/Cargo binaries, and it then responsible for downloading the stage0 compiler/Cargo binaries, and it then
compiles the build system itself (this folder). Finally, it then invokes the compiles the build system itself (this folder). Finally, it then invokes the
actual `boostrap` binary build system. actual `bootstrap` binary build system.
2. In Rust, `bootstrap` will slurp up all configuration, perform a number of 2. In Rust, `bootstrap` will slurp up all configuration, perform a number of
sanity checks (compilers exist for example), and then start building the sanity checks (compilers exist for example), and then start building the
stage0 artifacts. stage0 artifacts.

View File

@ -10,6 +10,7 @@
import argparse import argparse
import contextlib import contextlib
import datetime
import hashlib import hashlib
import os import os
import shutil import shutil
@ -18,6 +19,8 @@ import sys
import tarfile import tarfile
import tempfile import tempfile
from time import time
def get(url, path, verbose=False): def get(url, path, verbose=False):
sha_url = url + ".sha256" sha_url = url + ".sha256"
@ -30,7 +33,7 @@ def get(url, path, verbose=False):
download(sha_path, sha_url, verbose) download(sha_path, sha_url, verbose)
download(temp_path, url, verbose) download(temp_path, url, verbose)
verify(temp_path, sha_path, verbose) verify(temp_path, sha_path, verbose)
print("moving " + temp_path + " to " + path) print("moving {} to {}".format(temp_path, path))
shutil.move(temp_path, path) shutil.move(temp_path, path)
finally: finally:
delete_if_present(sha_path) delete_if_present(sha_path)
@ -44,7 +47,7 @@ def delete_if_present(path):
def download(path, url, verbose): def download(path, url, verbose):
print("downloading " + url + " to " + path) print("downloading {} to {}".format(url, path))
# see http://serverfault.com/questions/301128/how-to-download # see http://serverfault.com/questions/301128/how-to-download
if sys.platform == 'win32': if sys.platform == 'win32':
run(["PowerShell.exe", "/nologo", "-Command", run(["PowerShell.exe", "/nologo", "-Command",
@ -108,14 +111,18 @@ def run(args, verbose=False):
def stage0_data(rust_root): def stage0_data(rust_root):
nightlies = os.path.join(rust_root, "src/stage0.txt") nightlies = os.path.join(rust_root, "src/stage0.txt")
data = {}
with open(nightlies, 'r') as nightlies: with open(nightlies, 'r') as nightlies:
data = {} for line in nightlies:
for line in nightlies.read().split("\n"): line = line.rstrip() # Strip newline character, '\n'
if line.startswith("#") or line == '': if line.startswith("#") or line == '':
continue continue
a, b = line.split(": ", 1) a, b = line.split(": ", 1)
data[a] = b data[a] = b
return data return data
def format_build_time(duration):
return str(datetime.timedelta(seconds=int(duration)))
class RustBuild: class RustBuild:
def download_stage0(self): def download_stage0(self):
@ -132,20 +139,20 @@ class RustBuild:
if os.path.exists(self.bin_root()): if os.path.exists(self.bin_root()):
shutil.rmtree(self.bin_root()) shutil.rmtree(self.bin_root())
channel = self.stage0_rustc_channel() channel = self.stage0_rustc_channel()
filename = "rust-std-" + channel + "-" + self.build + ".tar.gz" filename = "rust-std-{}-{}.tar.gz".format(channel, self.build)
url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date() url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date()
tarball = os.path.join(rustc_cache, filename) tarball = os.path.join(rustc_cache, filename)
if not os.path.exists(tarball): if not os.path.exists(tarball):
get(url + "/" + filename, tarball, verbose=self.verbose) get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
unpack(tarball, self.bin_root(), unpack(tarball, self.bin_root(),
match="rust-std-" + self.build, match="rust-std-" + self.build,
verbose=self.verbose) verbose=self.verbose)
filename = "rustc-" + channel + "-" + self.build + ".tar.gz" filename = "rustc-{}-{}.tar.gz".format(channel, self.build)
url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date() url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date()
tarball = os.path.join(rustc_cache, filename) tarball = os.path.join(rustc_cache, filename)
if not os.path.exists(tarball): if not os.path.exists(tarball):
get(url + "/" + filename, tarball, verbose=self.verbose) get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
unpack(tarball, self.bin_root(), match="rustc", verbose=self.verbose) unpack(tarball, self.bin_root(), match="rustc", verbose=self.verbose)
with open(self.rustc_stamp(), 'w') as f: with open(self.rustc_stamp(), 'w') as f:
f.write(self.stage0_rustc_date()) f.write(self.stage0_rustc_date())
@ -153,11 +160,11 @@ class RustBuild:
if self.cargo().startswith(self.bin_root()) and \ if self.cargo().startswith(self.bin_root()) and \
(not os.path.exists(self.cargo()) or self.cargo_out_of_date()): (not os.path.exists(self.cargo()) or self.cargo_out_of_date()):
channel = self.stage0_cargo_channel() channel = self.stage0_cargo_channel()
filename = "cargo-" + channel + "-" + self.build + ".tar.gz" filename = "cargo-{}-{}.tar.gz".format(channel, self.build)
url = "https://static.rust-lang.org/cargo-dist/" + self.stage0_cargo_date() url = "https://static.rust-lang.org/cargo-dist/" + self.stage0_cargo_date()
tarball = os.path.join(cargo_cache, filename) tarball = os.path.join(cargo_cache, filename)
if not os.path.exists(tarball): if not os.path.exists(tarball):
get(url + "/" + filename, tarball, verbose=self.verbose) get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
unpack(tarball, self.bin_root(), match="cargo", verbose=self.verbose) unpack(tarball, self.bin_root(), match="cargo", verbose=self.verbose)
with open(self.cargo_stamp(), 'w') as f: with open(self.cargo_stamp(), 'w') as f:
f.write(self.stage0_cargo_date()) f.write(self.stage0_cargo_date())
@ -181,13 +188,13 @@ class RustBuild:
return os.path.join(self.bin_root(), '.cargo-stamp') return os.path.join(self.bin_root(), '.cargo-stamp')
def rustc_out_of_date(self): def rustc_out_of_date(self):
if not os.path.exists(self.rustc_stamp()): if not os.path.exists(self.rustc_stamp()) or self.clean:
return True return True
with open(self.rustc_stamp(), 'r') as f: with open(self.rustc_stamp(), 'r') as f:
return self.stage0_rustc_date() != f.read() return self.stage0_rustc_date() != f.read()
def cargo_out_of_date(self): def cargo_out_of_date(self):
if not os.path.exists(self.cargo_stamp()): if not os.path.exists(self.cargo_stamp()) or self.clean:
return True return True
with open(self.cargo_stamp(), 'r') as f: with open(self.cargo_stamp(), 'r') as f:
return self.stage0_cargo_date() != f.read() return self.stage0_cargo_date() != f.read()
@ -234,8 +241,11 @@ class RustBuild:
return '' return ''
def build_bootstrap(self): def build_bootstrap(self):
build_dir = os.path.join(self.build_dir, "bootstrap")
if self.clean and os.path.exists(build_dir):
shutil.rmtree(build_dir)
env = os.environ.copy() env = os.environ.copy()
env["CARGO_TARGET_DIR"] = os.path.join(self.build_dir, "bootstrap") env["CARGO_TARGET_DIR"] = build_dir
env["RUSTC"] = self.rustc() env["RUSTC"] = self.rustc()
env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") env["LD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib")
env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") env["DYLD_LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib")
@ -246,7 +256,7 @@ class RustBuild:
env) env)
def run(self, args, env): def run(self, args, env):
proc = subprocess.Popen(args, env = env) proc = subprocess.Popen(args, env=env)
ret = proc.wait() ret = proc.wait()
if ret != 0: if ret != 0:
sys.exit(ret) sys.exit(ret)
@ -261,20 +271,19 @@ class RustBuild:
try: try:
ostype = subprocess.check_output(['uname', '-s']).strip() ostype = subprocess.check_output(['uname', '-s']).strip()
cputype = subprocess.check_output(['uname', '-m']).strip() cputype = subprocess.check_output(['uname', '-m']).strip()
except FileNotFoundError: except (subprocess.CalledProcessError, WindowsError):
if sys.platform == 'win32': if sys.platform == 'win32':
return 'x86_64-pc-windows-msvc' return 'x86_64-pc-windows-msvc'
else: err = "uname not found"
err = "uname not found" if self.verbose:
if self.verbose: raise Exception(err)
raise Exception(err) sys.exit(err)
sys.exit(err)
# Darwin's `uname -s` lies and always returns i386. We have to use # Darwin's `uname -s` lies and always returns i386. We have to use
# sysctl instead. # sysctl instead.
if ostype == 'Darwin' and cputype == 'i686': if ostype == 'Darwin' and cputype == 'i686':
sysctl = subprocess.check_output(['sysctl', 'hw.optional.x86_64']) sysctl = subprocess.check_output(['sysctl', 'hw.optional.x86_64'])
if sysctl.contains(': 1'): if ': 1' in sysctl:
cputype = 'x86_64' cputype = 'x86_64'
# The goal here is to come up with the same triple as LLVM would, # The goal here is to come up with the same triple as LLVM would,
@ -335,11 +344,12 @@ class RustBuild:
raise ValueError(err) raise ValueError(err)
sys.exit(err) sys.exit(err)
return cputype + '-' + ostype return "{}-{}".format(cputype, ostype)
def main(): def main():
parser = argparse.ArgumentParser(description='Build rust') parser = argparse.ArgumentParser(description='Build rust')
parser.add_argument('--config') parser.add_argument('--config')
parser.add_argument('--clean', action='store_true')
parser.add_argument('-v', '--verbose', action='store_true') parser.add_argument('-v', '--verbose', action='store_true')
args = [a for a in sys.argv if a != '-h'] args = [a for a in sys.argv if a != '-h']
@ -352,6 +362,7 @@ def main():
rb.rust_root = os.path.abspath(os.path.join(__file__, '../../..')) rb.rust_root = os.path.abspath(os.path.join(__file__, '../../..'))
rb.build_dir = os.path.join(os.getcwd(), "build") rb.build_dir = os.path.join(os.getcwd(), "build")
rb.verbose = args.verbose rb.verbose = args.verbose
rb.clean = args.clean
try: try:
with open(args.config or 'config.toml') as config: with open(args.config or 'config.toml') as config:
@ -367,6 +378,8 @@ def main():
rb._rustc_channel, rb._rustc_date = data['rustc'].split('-', 1) rb._rustc_channel, rb._rustc_date = data['rustc'].split('-', 1)
rb._cargo_channel, rb._cargo_date = data['cargo'].split('-', 1) rb._cargo_channel, rb._cargo_date = data['cargo'].split('-', 1)
start_time = time()
# Fetch/build the bootstrap # Fetch/build the bootstrap
rb.build = rb.build_triple() rb.build = rb.build_triple()
rb.download_stage0() rb.download_stage0()
@ -385,5 +398,9 @@ def main():
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid()) env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
rb.run(args, env) rb.run(args, env)
end_time = time()
print("Build completed in %s" % format_build_time(end_time - start_time))
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -57,7 +57,9 @@ pub fn find(build: &mut Build) {
let compiler = cfg.get_compiler(); let compiler = cfg.get_compiler();
let ar = cc2ar(compiler.path(), target); let ar = cc2ar(compiler.path(), target);
build.verbose(&format!("CC_{} = {:?}", target, compiler.path())); build.verbose(&format!("CC_{} = {:?}", target, compiler.path()));
build.verbose(&format!("AR_{} = {:?}", target, ar)); if let Some(ref ar) = ar {
build.verbose(&format!("AR_{} = {:?}", target, ar));
}
build.cc.insert(target.to_string(), (compiler, ar)); build.cc.insert(target.to_string(), (compiler, ar));
} }
@ -88,6 +90,7 @@ fn set_compiler(cfg: &mut gcc::Config,
// compiler already takes into account the triple in question. // compiler already takes into account the triple in question.
t if t.contains("android") => { t if t.contains("android") => {
if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) { if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) {
let target = target.replace("armv7", "arm");
let compiler = format!("{}-{}", target, gnu_compiler); let compiler = format!("{}-{}", target, gnu_compiler);
cfg.compiler(ndk.join("bin").join(compiler)); cfg.compiler(ndk.join("bin").join(compiler));
} }

View File

@ -23,6 +23,9 @@ use build_helper::output;
use bootstrap::{dylib_path, dylib_path_var}; use bootstrap::{dylib_path, dylib_path_var};
use build::{Build, Compiler, Mode}; use build::{Build, Compiler, Mode};
use build::util;
const ADB_TEST_DIR: &'static str = "/data/tmp";
/// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler. /// Runs the `linkchecker` tool as compiled in `stage` by the `host` compiler.
/// ///
@ -88,6 +91,7 @@ pub fn compiletest(build: &Build,
target: &str, target: &str,
mode: &str, mode: &str,
suite: &str) { suite: &str) {
println!("Check compiletest {} ({} -> {})", suite, compiler.host, target);
let mut cmd = build.tool_cmd(compiler, "compiletest"); let mut cmd = build.tool_cmd(compiler, "compiletest");
// compiletest currently has... a lot of arguments, so let's just pass all // compiletest currently has... a lot of arguments, so let's just pass all
@ -105,21 +109,23 @@ pub fn compiletest(build: &Build,
cmd.arg("--host").arg(compiler.host); cmd.arg("--host").arg(compiler.host);
cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.config.build)); cmd.arg("--llvm-filecheck").arg(build.llvm_filecheck(&build.config.build));
let mut flags = format!("-Crpath"); let mut flags = vec!["-Crpath".to_string()];
if build.config.rust_optimize_tests { if build.config.rust_optimize_tests {
flags.push_str(" -O"); flags.push("-O".to_string());
} }
if build.config.rust_debuginfo_tests { if build.config.rust_debuginfo_tests {
flags.push_str(" -g"); flags.push("-g".to_string());
} }
cmd.arg("--host-rustcflags").arg(&flags); let mut hostflags = build.rustc_flags(&compiler.host);
hostflags.extend(flags.clone());
cmd.arg("--host-rustcflags").arg(hostflags.join(" "));
let linkflag = format!("-Lnative={}", build.test_helpers_out(target).display()); let mut targetflags = build.rustc_flags(&target);
cmd.arg("--target-rustcflags").arg(format!("{} {}", flags, linkflag)); targetflags.extend(flags);
targetflags.push(format!("-Lnative={}",
// FIXME: needs android support build.test_helpers_out(target).display()));
cmd.arg("--android-cross-path").arg(""); cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
// FIXME: CFG_PYTHON should probably be detected more robustly elsewhere // FIXME: CFG_PYTHON should probably be detected more robustly elsewhere
let python_default = "python"; let python_default = "python";
@ -180,6 +186,16 @@ pub fn compiletest(build: &Build,
} }
build.add_bootstrap_key(compiler, &mut cmd); build.add_bootstrap_key(compiler, &mut cmd);
cmd.arg("--adb-path").arg("adb");
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
if target.contains("android") {
// Assume that cc for this target comes from the android sysroot
cmd.arg("--android-cross-path")
.arg(build.cc(target).parent().unwrap().parent().unwrap());
} else {
cmd.arg("--android-cross-path").arg("");
}
build.run(&mut cmd); build.run(&mut cmd);
} }
@ -302,7 +318,97 @@ pub fn krate(build: &Build,
let mut dylib_path = dylib_path(); let mut dylib_path = dylib_path();
dylib_path.insert(0, build.sysroot_libdir(compiler, target)); dylib_path.insert(0, build.sysroot_libdir(compiler, target));
cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
cargo.args(&build.flags.args);
build.run(&mut cargo); if target.contains("android") {
build.run(cargo.arg("--no-run"));
krate_android(build, compiler, target, mode);
} else {
cargo.args(&build.flags.args);
build.run(&mut cargo);
}
}
fn krate_android(build: &Build,
compiler: &Compiler,
target: &str,
mode: Mode) {
let mut tests = Vec::new();
let out_dir = build.cargo_out(compiler, mode, target);
find_tests(&out_dir, target, &mut tests);
find_tests(&out_dir.join("deps"), target, &mut tests);
for test in tests {
build.run(Command::new("adb").arg("push").arg(&test).arg(ADB_TEST_DIR));
let test_file_name = test.file_name().unwrap().to_string_lossy();
let log = format!("{}/check-stage{}-T-{}-H-{}-{}.log",
ADB_TEST_DIR,
compiler.stage,
target,
compiler.host,
test_file_name);
let program = format!("(cd {dir}; \
LD_LIBRARY_PATH=./{target} ./{test} \
--logfile {log} \
{args})",
dir = ADB_TEST_DIR,
target = target,
test = test_file_name,
log = log,
args = build.flags.args.join(" "));
let output = output(Command::new("adb").arg("shell").arg(&program));
println!("{}", output);
build.run(Command::new("adb")
.arg("pull")
.arg(&log)
.arg(build.out.join("tmp")));
build.run(Command::new("adb").arg("shell").arg("rm").arg(&log));
if !output.contains("result: ok") {
panic!("some tests failed");
}
}
}
fn find_tests(dir: &Path,
target: &str,
dst: &mut Vec<PathBuf>) {
for e in t!(dir.read_dir()).map(|e| t!(e)) {
let file_type = t!(e.file_type());
if !file_type.is_file() {
continue
}
let filename = e.file_name().into_string().unwrap();
if (target.contains("windows") && filename.ends_with(".exe")) ||
(!target.contains("windows") && !filename.contains(".")) {
dst.push(e.path());
}
}
}
pub fn android_copy_libs(build: &Build,
compiler: &Compiler,
target: &str) {
println!("Android copy libs to emulator ({})", target);
build.run(Command::new("adb").arg("remount"));
build.run(Command::new("adb").args(&["shell", "rm", "-r", ADB_TEST_DIR]));
build.run(Command::new("adb").args(&["shell", "mkdir", ADB_TEST_DIR]));
build.run(Command::new("adb")
.arg("push")
.arg(build.src.join("src/etc/adb_run_wrapper.sh"))
.arg(ADB_TEST_DIR));
let target_dir = format!("{}/{}", ADB_TEST_DIR, target);
build.run(Command::new("adb").args(&["shell", "mkdir", &target_dir[..]]));
for f in t!(build.sysroot_libdir(compiler, target).read_dir()) {
let f = t!(f);
let name = f.file_name().into_string().unwrap();
if util::is_dylib(&name) {
build.run(Command::new("adb")
.arg("push")
.arg(f.path())
.arg(&target_dir));
}
}
} }

View File

@ -21,6 +21,9 @@ use std::path::Path;
use build::Build; use build::Build;
pub fn clean(build: &Build) { pub fn clean(build: &Build) {
rm_rf(build, "tmp".as_ref());
rm_rf(build, &build.out.join("tmp"));
for host in build.config.host.iter() { for host in build.config.host.iter() {
let out = build.out.join(host); let out = build.out.join(host);

View File

@ -65,8 +65,9 @@ pub struct Config {
pub build: String, pub build: String,
pub host: Vec<String>, pub host: Vec<String>,
pub target: Vec<String>, pub target: Vec<String>,
pub rustc: Option<String>, pub rustc: Option<PathBuf>,
pub cargo: Option<String>, pub cargo: Option<PathBuf>,
pub local_rebuild: bool,
// libstd features // libstd features
pub debug_jemalloc: bool, pub debug_jemalloc: bool,
@ -207,8 +208,8 @@ impl Config {
config.target.push(target.clone()); config.target.push(target.clone());
} }
} }
config.rustc = build.rustc; config.rustc = build.rustc.map(PathBuf::from);
config.cargo = build.cargo; config.cargo = build.cargo.map(PathBuf::from);
set(&mut config.compiler_docs, build.compiler_docs); set(&mut config.compiler_docs, build.compiler_docs);
set(&mut config.docs, build.docs); set(&mut config.docs, build.docs);
@ -315,6 +316,7 @@ impl Config {
("RPATH", self.rust_rpath), ("RPATH", self.rust_rpath),
("OPTIMIZE_TESTS", self.rust_optimize_tests), ("OPTIMIZE_TESTS", self.rust_optimize_tests),
("DEBUGINFO_TESTS", self.rust_debuginfo_tests), ("DEBUGINFO_TESTS", self.rust_debuginfo_tests),
("LOCAL_REBUILD", self.local_rebuild),
} }
match key { match key {
@ -366,17 +368,21 @@ impl Config {
target.ndk = Some(PathBuf::from(value)); target.ndk = Some(PathBuf::from(value));
} }
"CFG_I686_LINUX_ANDROID_NDK" if value.len() > 0 => { "CFG_I686_LINUX_ANDROID_NDK" if value.len() > 0 => {
let target = "i686-linux-androideabi".to_string(); let target = "i686-linux-android".to_string();
let target = self.target_config.entry(target) let target = self.target_config.entry(target)
.or_insert(Target::default()); .or_insert(Target::default());
target.ndk = Some(PathBuf::from(value)); target.ndk = Some(PathBuf::from(value));
} }
"CFG_AARCH64_LINUX_ANDROID_NDK" if value.len() > 0 => { "CFG_AARCH64_LINUX_ANDROID_NDK" if value.len() > 0 => {
let target = "aarch64-linux-androideabi".to_string(); let target = "aarch64-linux-android".to_string();
let target = self.target_config.entry(target) let target = self.target_config.entry(target)
.or_insert(Target::default()); .or_insert(Target::default());
target.ndk = Some(PathBuf::from(value)); target.ndk = Some(PathBuf::from(value));
} }
"CFG_LOCAL_RUST_ROOT" if value.len() > 0 => {
self.rustc = Some(PathBuf::from(value).join("bin/rustc"));
self.cargo = Some(PathBuf::from(value).join("bin/cargo"));
}
_ => {} _ => {}
} }
} }

View File

@ -135,7 +135,6 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
// Prepare the overlay which is part of the tarball but won't actually be // Prepare the overlay which is part of the tarball but won't actually be
// installed // installed
t!(fs::create_dir_all(&overlay));
let cp = |file: &str| { let cp = |file: &str| {
install(&build.src.join(file), &overlay, 0o644); install(&build.src.join(file), &overlay, 0o644);
}; };
@ -199,7 +198,6 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
// Copy runtime DLLs needed by the compiler // Copy runtime DLLs needed by the compiler
if libdir != "bin" { if libdir != "bin" {
t!(fs::create_dir_all(image.join(libdir)));
for entry in t!(src.join(libdir).read_dir()).map(|e| t!(e)) { for entry in t!(src.join(libdir).read_dir()).map(|e| t!(e)) {
let name = entry.file_name(); let name = entry.file_name();
if let Some(s) = name.to_str() { if let Some(s) = name.to_str() {
@ -221,7 +219,6 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
let cp = |file: &str| { let cp = |file: &str| {
install(&build.src.join(file), &image.join("share/doc/rust"), 0o644); install(&build.src.join(file), &image.join("share/doc/rust"), 0o644);
}; };
t!(fs::create_dir_all(&image.join("share/doc/rust")));
cp("COPYRIGHT"); cp("COPYRIGHT");
cp("LICENSE-APACHE"); cp("LICENSE-APACHE");
cp("LICENSE-MIT"); cp("LICENSE-MIT");
@ -289,6 +286,7 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
fn install(src: &Path, dstdir: &Path, perms: u32) { fn install(src: &Path, dstdir: &Path, perms: u32) {
let dst = dstdir.join(src.file_name().unwrap()); let dst = dstdir.join(src.file_name().unwrap());
t!(fs::create_dir_all(dstdir));
t!(fs::copy(src, &dst)); t!(fs::copy(src, &dst));
chmod(&dst, perms); chmod(&dst, perms);
} }

View File

@ -119,7 +119,7 @@ pub struct Build {
lldb_python_dir: Option<String>, lldb_python_dir: Option<String>,
// Runtime state filled in later on // Runtime state filled in later on
cc: HashMap<String, (gcc::Tool, PathBuf)>, cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
cxx: HashMap<String, gcc::Tool>, cxx: HashMap<String, gcc::Tool>,
compiler_rt_built: RefCell<HashMap<String, PathBuf>>, compiler_rt_built: RefCell<HashMap<String, PathBuf>>,
} }
@ -128,6 +128,7 @@ pub struct Build {
/// ///
/// These entries currently correspond to the various output directories of the /// These entries currently correspond to the various output directories of the
/// build system, with each mod generating output in a different directory. /// build system, with each mod generating output in a different directory.
#[derive(Clone, Copy)]
pub enum Mode { pub enum Mode {
/// This cargo is going to build the standard library, placing output in the /// This cargo is going to build the standard library, placing output in the
/// "stageN-std" directory. /// "stageN-std" directory.
@ -383,8 +384,7 @@ impl Build {
"ui", "ui"); "ui", "ui");
} }
CheckDebuginfo { compiler } => { CheckDebuginfo { compiler } => {
if target.target.contains("msvc") || if target.target.contains("msvc") {
target.target.contains("android") {
// nothing to do // nothing to do
} else if target.target.contains("apple") { } else if target.target.contains("apple") {
check::compiletest(self, &compiler, target.target, check::compiletest(self, &compiler, target.target,
@ -434,8 +434,14 @@ impl Build {
target.target); target.target);
} }
AndroidCopyLibs { compiler } => {
check::android_copy_libs(self, &compiler, target.target);
}
// pseudo-steps
Dist { .. } | Dist { .. } |
Doc { .. } | // pseudo-steps Doc { .. } |
CheckTarget { .. } |
Check { .. } => {} Check { .. } => {}
} }
} }
@ -510,6 +516,14 @@ impl Build {
.arg("-j").arg(self.jobs().to_string()) .arg("-j").arg(self.jobs().to_string())
.arg("--target").arg(target); .arg("--target").arg(target);
let stage;
if compiler.stage == 0 && self.config.local_rebuild {
// Assume the local-rebuild rustc already has stage1 features.
stage = 1;
} else {
stage = compiler.stage;
}
// Customize the compiler we're running. Specify the compiler to cargo // Customize the compiler we're running. Specify the compiler to cargo
// as our shim and then pass it some various options used to configure // as our shim and then pass it some various options used to configure
// how the actual compiler itself is called. // how the actual compiler itself is called.
@ -518,7 +532,7 @@ impl Build {
// src/bootstrap/{rustc,rustdoc.rs} // src/bootstrap/{rustc,rustdoc.rs}
cargo.env("RUSTC", self.out.join("bootstrap/debug/rustc")) cargo.env("RUSTC", self.out.join("bootstrap/debug/rustc"))
.env("RUSTC_REAL", self.compiler_path(compiler)) .env("RUSTC_REAL", self.compiler_path(compiler))
.env("RUSTC_STAGE", compiler.stage.to_string()) .env("RUSTC_STAGE", stage.to_string())
.env("RUSTC_DEBUGINFO", self.config.rust_debuginfo.to_string()) .env("RUSTC_DEBUGINFO", self.config.rust_debuginfo.to_string())
.env("RUSTC_CODEGEN_UNITS", .env("RUSTC_CODEGEN_UNITS",
self.config.rust_codegen_units.to_string()) self.config.rust_codegen_units.to_string())
@ -541,7 +555,7 @@ impl Build {
// FIXME: the guard against msvc shouldn't need to be here // FIXME: the guard against msvc shouldn't need to be here
if !target.contains("msvc") { if !target.contains("msvc") {
cargo.env(format!("CC_{}", target), self.cc(target)) cargo.env(format!("CC_{}", target), self.cc(target))
.env(format!("AR_{}", target), self.ar(target)) .env(format!("AR_{}", target), self.ar(target).unwrap()) // only msvc is None
.env(format!("CFLAGS_{}", target), self.cflags(target).join(" ")); .env(format!("CFLAGS_{}", target), self.cflags(target).join(" "));
} }
@ -744,7 +758,7 @@ impl Build {
// In stage0 we're using a previously released stable compiler, so we // In stage0 we're using a previously released stable compiler, so we
// use the stage0 bootstrap key. Otherwise we use our own build's // use the stage0 bootstrap key. Otherwise we use our own build's
// bootstrap key. // bootstrap key.
let bootstrap_key = if compiler.is_snapshot(self) { let bootstrap_key = if compiler.is_snapshot(self) && !self.config.local_rebuild {
&self.bootstrap_key_stage0 &self.bootstrap_key_stage0
} else { } else {
&self.bootstrap_key &self.bootstrap_key
@ -817,8 +831,8 @@ impl Build {
} }
/// Returns the path to the `ar` archive utility for the target specified. /// Returns the path to the `ar` archive utility for the target specified.
fn ar(&self, target: &str) -> &Path { fn ar(&self, target: &str) -> Option<&Path> {
&self.cc[target].1 self.cc[target].1.as_ref().map(|p| &**p)
} }
/// Returns the path to the C++ compiler for the target specified, may panic /// Returns the path to the C++ compiler for the target specified, may panic

View File

@ -20,14 +20,14 @@
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::fs; use std::fs::{self, File};
use build_helper::output; use build_helper::output;
use cmake; use cmake;
use gcc; use gcc;
use build::Build; use build::Build;
use build::util::{exe, staticlib, up_to_date}; use build::util::{staticlib, up_to_date};
/// Compile LLVM for `target`. /// Compile LLVM for `target`.
pub fn llvm(build: &Build, target: &str) { pub fn llvm(build: &Build, target: &str) {
@ -43,12 +43,14 @@ pub fn llvm(build: &Build, target: &str) {
// artifacts are missing) then we keep going, otherwise we bail out. // artifacts are missing) then we keep going, otherwise we bail out.
let dst = build.llvm_out(target); let dst = build.llvm_out(target);
let stamp = build.src.join("src/rustllvm/llvm-auto-clean-trigger"); let stamp = build.src.join("src/rustllvm/llvm-auto-clean-trigger");
let llvm_config = dst.join("bin").join(exe("llvm-config", target)); let done_stamp = dst.join("llvm-finished-building");
build.clear_if_dirty(&dst, &stamp); build.clear_if_dirty(&dst, &stamp);
if fs::metadata(llvm_config).is_ok() { if fs::metadata(&done_stamp).is_ok() {
return return
} }
println!("Building LLVM for {}", target);
let _ = fs::remove_dir_all(&dst.join("build")); let _ = fs::remove_dir_all(&dst.join("build"));
t!(fs::create_dir_all(&dst.join("build"))); t!(fs::create_dir_all(&dst.join("build")));
let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"}; let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};
@ -111,6 +113,8 @@ pub fn llvm(build: &Build, target: &str) {
// tools. Figure out how to filter them down and only build the right // tools. Figure out how to filter them down and only build the right
// tools and libs on all platforms. // tools and libs on all platforms.
cfg.build(); cfg.build();
t!(File::create(&done_stamp));
} }
fn check_llvm_version(build: &Build, llvm_config: &Path) { fn check_llvm_version(build: &Build, llvm_config: &Path) {
@ -135,39 +139,7 @@ pub fn compiler_rt(build: &Build, target: &str) {
let dst = build.compiler_rt_out(target); let dst = build.compiler_rt_out(target);
let arch = target.split('-').next().unwrap(); let arch = target.split('-').next().unwrap();
let mode = if build.config.rust_optimize {"Release"} else {"Debug"}; let mode = if build.config.rust_optimize {"Release"} else {"Debug"};
let (dir, build_target, libname) = if target.contains("linux") ||
target.contains("freebsd") ||
target.contains("netbsd") {
let os = if target.contains("android") {"-android"} else {""};
let arch = if arch.starts_with("arm") && target.contains("eabihf") {
"armhf"
} else {
arch
};
let target = format!("clang_rt.builtins-{}{}", arch, os);
("linux".to_string(), target.clone(), target)
} else if target.contains("darwin") {
let target = format!("clang_rt.builtins_{}_osx", arch);
("builtins".to_string(), target.clone(), target)
} else if target.contains("windows-gnu") {
let target = format!("clang_rt.builtins-{}", arch);
("windows".to_string(), target.clone(), target)
} else if target.contains("windows-msvc") {
(format!("windows/{}", mode),
"lib/builtins/builtins".to_string(),
format!("clang_rt.builtins-{}", arch.replace("i686", "i386")))
} else {
panic!("can't get os from target: {}", target)
};
let output = dst.join("build/lib").join(dir)
.join(staticlib(&libname, target));
build.compiler_rt_built.borrow_mut().insert(target.to_string(),
output.clone());
if fs::metadata(&output).is_ok() {
return
}
let _ = fs::remove_dir_all(&dst);
t!(fs::create_dir_all(&dst));
let build_llvm_config = build.llvm_config(&build.config.build); let build_llvm_config = build.llvm_config(&build.config.build);
let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt")); let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
cfg.target(target) cfg.target(target)
@ -181,8 +153,65 @@ pub fn compiler_rt(build: &Build, target: &str) {
// inform about c/c++ compilers, the c++ compiler isn't actually used but // inform about c/c++ compilers, the c++ compiler isn't actually used but
// it's needed to get the initial configure to work on all platforms. // it's needed to get the initial configure to work on all platforms.
.define("CMAKE_C_COMPILER", build.cc(target)) .define("CMAKE_C_COMPILER", build.cc(target))
.define("CMAKE_CXX_COMPILER", build.cc(target)) .define("CMAKE_CXX_COMPILER", build.cc(target));
.build_target(&build_target);
let (dir, build_target, libname) = if target.contains("linux") ||
target.contains("freebsd") ||
target.contains("netbsd") {
let os_extra = if target.contains("android") && target.contains("arm") {
"-android"
} else {
""
};
let builtins_arch = match arch {
"i586" => "i386",
"arm" | "armv7" if target.contains("android") => "armhf",
"arm" if target.contains("eabihf") => "armhf",
_ => arch,
};
let target = format!("clang_rt.builtins-{}", builtins_arch);
("linux".to_string(),
target.clone(),
format!("{}{}", target, os_extra))
} else if target.contains("apple-darwin") {
let builtins_arch = match arch {
"i686" => "i386",
_ => arch,
};
let target = format!("clang_rt.builtins_{}_osx", builtins_arch);
("builtins".to_string(), target.clone(), target)
} else if target.contains("apple-ios") {
cfg.define("COMPILER_RT_ENABLE_IOS", "ON");
let target = match arch {
"armv7s" => "hard_pic_armv7em_macho_embedded".to_string(),
"aarch64" => "builtins_arm64_ios".to_string(),
_ => format!("hard_pic_{}_macho_embedded", arch),
};
("builtins".to_string(), target.clone(), target)
} else if target.contains("windows-gnu") {
let target = format!("clang_rt.builtins-{}", arch);
("windows".to_string(), target.clone(), target)
} else if target.contains("windows-msvc") {
let builtins_arch = match arch {
"i586" | "i686" => "i386",
_ => arch,
};
(format!("windows/{}", mode),
"lib/builtins/builtins".to_string(),
format!("clang_rt.builtins-{}", builtins_arch))
} else {
panic!("can't get os from target: {}", target)
};
let output = dst.join("build/lib").join(dir)
.join(staticlib(&libname, target));
build.compiler_rt_built.borrow_mut().insert(target.to_string(),
output.clone());
if fs::metadata(&output).is_ok() {
return
}
let _ = fs::remove_dir_all(&dst);
t!(fs::create_dir_all(&dst));
cfg.build_target(&build_target);
cfg.build(); cfg.build();
} }

View File

@ -70,7 +70,9 @@ pub fn check(build: &mut Build) {
// also build some C++ shims for LLVM so we need a C++ compiler. // also build some C++ shims for LLVM so we need a C++ compiler.
for target in build.config.target.iter() { for target in build.config.target.iter() {
need_cmd(build.cc(target).as_ref()); need_cmd(build.cc(target).as_ref());
need_cmd(build.ar(target).as_ref()); if let Some(ar) = build.ar(target) {
need_cmd(ar.as_ref());
}
} }
for host in build.config.host.iter() { for host in build.config.host.iter() {
need_cmd(build.cxx(host).as_ref()); need_cmd(build.cxx(host).as_ref());
@ -137,6 +139,10 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
"); ");
} }
} }
if target.contains("arm-linux-android") {
need_cmd("adb".as_ref());
}
} }
for host in build.flags.host.iter() { for host in build.flags.host.iter() {

View File

@ -102,6 +102,7 @@ macro_rules! targets {
// Steps for running tests. The 'check' target is just a pseudo // Steps for running tests. The 'check' target is just a pseudo
// target to depend on a bunch of others. // target to depend on a bunch of others.
(check, Check { stage: u32, compiler: Compiler<'a> }), (check, Check { stage: u32, compiler: Compiler<'a> }),
(check_target, CheckTarget { stage: u32, compiler: Compiler<'a> }),
(check_linkcheck, CheckLinkcheck { stage: u32 }), (check_linkcheck, CheckLinkcheck { stage: u32 }),
(check_cargotest, CheckCargoTest { stage: u32 }), (check_cargotest, CheckCargoTest { stage: u32 }),
(check_tidy, CheckTidy { stage: u32 }), (check_tidy, CheckTidy { stage: u32 }),
@ -138,6 +139,9 @@ macro_rules! targets {
(dist_mingw, DistMingw { _dummy: () }), (dist_mingw, DistMingw { _dummy: () }),
(dist_rustc, DistRustc { stage: u32 }), (dist_rustc, DistRustc { stage: u32 }),
(dist_std, DistStd { compiler: Compiler<'a> }), (dist_std, DistStd { compiler: Compiler<'a> }),
// Misc targets
(android_copy_libs, AndroidCopyLibs { compiler: Compiler<'a> }),
} }
} }
} }
@ -382,37 +386,80 @@ impl<'a> Step<'a> {
self.doc_error_index(stage)] self.doc_error_index(stage)]
} }
Source::Check { stage, compiler } => { Source::Check { stage, compiler } => {
vec![ // Check is just a pseudo step which means check all targets,
// so just depend on checking all targets.
build.config.target.iter().map(|t| {
self.target(t).check_target(stage, compiler)
}).collect()
}
Source::CheckTarget { stage, compiler } => {
// CheckTarget here means run all possible test suites for this
// target. Most of the time, however, we can't actually run
// anything if we're not the build triple as we could be cross
// compiling.
//
// As a result, the base set of targets here is quite stripped
// down from the standard set of targets. These suites have
// their own internal logic to run in cross-compiled situations
// if they'll run at all. For example compiletest knows that
// when testing Android targets we ship artifacts to the
// emulator.
//
// When in doubt the rule of thumb for adding to this list is
// "should this test suite run on the android bot?"
let mut base = vec![
self.check_rpass(compiler), self.check_rpass(compiler),
self.check_rpass_full(compiler),
self.check_rfail(compiler), self.check_rfail(compiler),
self.check_rfail_full(compiler),
self.check_cfail(compiler),
self.check_cfail_full(compiler),
self.check_pfail(compiler),
self.check_incremental(compiler),
self.check_ui(compiler),
self.check_crate_std(compiler), self.check_crate_std(compiler),
self.check_crate_test(compiler), self.check_crate_test(compiler),
self.check_crate_rustc(compiler),
self.check_codegen(compiler),
self.check_codegen_units(compiler),
self.check_debuginfo(compiler), self.check_debuginfo(compiler),
self.check_rustdoc(compiler),
self.check_pretty(compiler),
self.check_pretty_rpass(compiler),
self.check_pretty_rpass_full(compiler),
self.check_pretty_rfail(compiler),
self.check_pretty_rfail_full(compiler),
self.check_pretty_rpass_valgrind(compiler),
self.check_rpass_valgrind(compiler),
self.check_error_index(compiler),
self.check_docs(compiler),
self.check_rmake(compiler),
self.check_linkcheck(stage),
self.check_tidy(stage),
self.dist(stage), self.dist(stage),
] ];
// If we're testing the build triple, then we know we can
// actually run binaries and such, so we run all possible tests
// that we know about.
if self.target == build.config.build {
base.extend(vec![
// docs-related
self.check_docs(compiler),
self.check_error_index(compiler),
self.check_rustdoc(compiler),
// UI-related
self.check_cfail(compiler),
self.check_pfail(compiler),
self.check_ui(compiler),
// codegen-related
self.check_incremental(compiler),
self.check_codegen(compiler),
self.check_codegen_units(compiler),
// misc compiletest-test suites
self.check_rpass_full(compiler),
self.check_rfail_full(compiler),
self.check_cfail_full(compiler),
self.check_pretty_rpass_full(compiler),
self.check_pretty_rfail_full(compiler),
self.check_rpass_valgrind(compiler),
self.check_rmake(compiler),
// crates
self.check_crate_rustc(compiler),
// pretty
self.check_pretty(compiler),
self.check_pretty_rpass(compiler),
self.check_pretty_rfail(compiler),
self.check_pretty_rpass_valgrind(compiler),
// misc
self.check_linkcheck(stage),
self.check_tidy(stage),
]);
}
return base
} }
Source::CheckLinkcheck { stage } => { Source::CheckLinkcheck { stage } => {
vec![self.tool_linkchecker(stage), self.doc(stage)] vec![self.tool_linkchecker(stage), self.doc(stage)]
@ -437,16 +484,20 @@ impl<'a> Step<'a> {
Source::CheckCFail { compiler } | Source::CheckCFail { compiler } |
Source::CheckRPassValgrind { compiler } | Source::CheckRPassValgrind { compiler } |
Source::CheckRPass { compiler } => { Source::CheckRPass { compiler } => {
vec![ let mut base = vec![
self.libtest(compiler), self.libtest(compiler),
self.tool_compiletest(compiler.stage), self.target(compiler.host).tool_compiletest(compiler.stage),
self.test_helpers(()), self.test_helpers(()),
] ];
if self.target.contains("android") {
base.push(self.android_copy_libs(compiler));
}
base
} }
Source::CheckDebuginfo { compiler } => { Source::CheckDebuginfo { compiler } => {
vec![ vec![
self.libtest(compiler), self.libtest(compiler),
self.tool_compiletest(compiler.stage), self.target(compiler.host).tool_compiletest(compiler.stage),
self.test_helpers(()), self.test_helpers(()),
self.debugger_scripts(compiler.stage), self.debugger_scripts(compiler.stage),
] ]
@ -459,13 +510,14 @@ impl<'a> Step<'a> {
Source::CheckPrettyRPassValgrind { compiler } | Source::CheckPrettyRPassValgrind { compiler } |
Source::CheckRMake { compiler } => { Source::CheckRMake { compiler } => {
vec![self.librustc(compiler), vec![self.librustc(compiler),
self.tool_compiletest(compiler.stage)] self.target(compiler.host).tool_compiletest(compiler.stage)]
} }
Source::CheckDocs { compiler } => { Source::CheckDocs { compiler } => {
vec![self.libstd(compiler)] vec![self.libstd(compiler)]
} }
Source::CheckErrorIndex { compiler } => { Source::CheckErrorIndex { compiler } => {
vec![self.libstd(compiler), self.tool_error_index(compiler.stage)] vec![self.libstd(compiler),
self.target(compiler.host).tool_error_index(compiler.stage)]
} }
Source::CheckCrateStd { compiler } => { Source::CheckCrateStd { compiler } => {
vec![self.libtest(compiler)] vec![self.libtest(compiler)]
@ -529,6 +581,10 @@ impl<'a> Step<'a> {
} }
return base return base
} }
Source::AndroidCopyLibs { compiler } => {
vec![self.libtest(compiler)]
}
} }
} }
} }

View File

@ -25,6 +25,11 @@ all:
clean: clean:
$(Q)$(BOOTSTRAP) --clean $(Q)$(BOOTSTRAP) --clean
rustc-stage1:
$(Q)$(BOOTSTRAP) --step libtest --stage 1
rustc-stage2:
$(Q)$(BOOTSTRAP) --step libtest --stage 2
docs: doc docs: doc
doc: doc:
$(Q)$(BOOTSTRAP) --step doc $(Q)$(BOOTSTRAP) --step doc

View File

@ -39,9 +39,11 @@ pub fn gnu_target(target: &str) -> String {
} }
} }
pub fn cc2ar(cc: &Path, target: &str) -> PathBuf { pub fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
if target.contains("musl") || target.contains("msvc") { if target.contains("msvc") {
PathBuf::from("ar") None
} else if target.contains("musl") {
Some(PathBuf::from("ar"))
} else { } else {
let parent = cc.parent().unwrap(); let parent = cc.parent().unwrap();
let file = cc.file_name().unwrap().to_str().unwrap(); let file = cc.file_name().unwrap().to_str().unwrap();
@ -49,10 +51,10 @@ pub fn cc2ar(cc: &Path, target: &str) -> PathBuf {
if let Some(idx) = file.rfind(suffix) { if let Some(idx) = file.rfind(suffix) {
let mut file = file[..idx].to_owned(); let mut file = file[..idx].to_owned();
file.push_str("ar"); file.push_str("ar");
return parent.join(&file); return Some(parent.join(&file));
} }
} }
parent.join(file) Some(parent.join(file))
} }
} }

View File

@ -66,8 +66,10 @@ if (NOT COMPILER_RT_STANDALONE_BUILD)
# Windows where we need to use clang-cl instead. # Windows where we need to use clang-cl instead.
if(NOT MSVC) if(NOT MSVC)
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang) set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
else() else()
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe) set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe)
set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++.exe)
endif() endif()
else() else()
# Take output dir and install path from the user. # Take output dir and install path from the user.
@ -81,6 +83,7 @@ else()
option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF) option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF)
# Use a host compiler to compile/link tests. # Use a host compiler to compile/link tests.
set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing") set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing")
set(COMPILER_RT_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "C++ Compiler to use for testing")
if (NOT LLVM_CONFIG_PATH) if (NOT LLVM_CONFIG_PATH)
find_program(LLVM_CONFIG_PATH "llvm-config" find_program(LLVM_CONFIG_PATH "llvm-config"
@ -189,6 +192,8 @@ else()
endif() endif()
option(COMPILER_RT_DEBUG "Build runtimes with full debug info" OFF) option(COMPILER_RT_DEBUG "Build runtimes with full debug info" OFF)
option(COMPILER_RT_EXTERNALIZE_DEBUGINFO
"Generate dSYM files and strip executables and libraries (Darwin Only)" OFF)
# COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in. # COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in.
pythonize_bool(COMPILER_RT_DEBUG) pythonize_bool(COMPILER_RT_DEBUG)
@ -226,6 +231,7 @@ append_list_if(COMPILER_RT_HAS_FUNWIND_TABLES_FLAG -funwind-tables SANITIZER_COM
append_list_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG -fno-stack-protector SANITIZER_COMMON_CFLAGS) append_list_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG -fno-stack-protector SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG -fno-sanitize=safe-stack SANITIZER_COMMON_CFLAGS) append_list_if(COMPILER_RT_HAS_FNO_SANITIZE_SAFE_STACK_FLAG -fno-sanitize=safe-stack SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SANITIZER_COMMON_CFLAGS) append_list_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FVISIBILITY_INLINES_HIDDEN_FLAG -fvisibility-inlines-hidden SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG -fno-function-sections SANITIZER_COMMON_CFLAGS) append_list_if(COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG -fno-function-sections SANITIZER_COMMON_CFLAGS)
append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS) append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)

View File

@ -19,7 +19,7 @@ function(add_compiler_rt_object_libraries name)
set(libname "${name}.${os}") set(libname "${name}.${os}")
set(libnames ${libnames} ${libname}) set(libnames ${libnames} ${libname})
set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS}) set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS})
list_union(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS) list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
endforeach() endforeach()
else() else()
foreach(arch ${LIB_ARCHS}) foreach(arch ${LIB_ARCHS})
@ -87,7 +87,7 @@ function(add_compiler_rt_runtime name type)
set(libname "${name}_${os}_dynamic") set(libname "${name}_${os}_dynamic")
set(extra_linkflags_${libname} ${DARWIN_${os}_LINKFLAGS} ${LIB_LINKFLAGS}) set(extra_linkflags_${libname} ${DARWIN_${os}_LINKFLAGS} ${LIB_LINKFLAGS})
endif() endif()
list_union(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS) list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
if(LIB_ARCHS_${libname}) if(LIB_ARCHS_${libname})
list(APPEND libnames ${libname}) list(APPEND libnames ${libname})
set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${LIB_CFLAGS}) set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${LIB_CFLAGS})
@ -155,6 +155,10 @@ function(add_compiler_rt_runtime name type)
set_target_properties(${libname} PROPERTIES set_target_properties(${libname} PROPERTIES
OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}") OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
endif() endif()
if(type STREQUAL "SHARED")
rt_externalize_debuginfo(${libname})
endif()
endforeach() endforeach()
if(LIB_PARENT_TARGET) if(LIB_PARENT_TARGET)
add_dependencies(${LIB_PARENT_TARGET} ${libnames}) add_dependencies(${LIB_PARENT_TARGET} ${libnames})
@ -284,12 +288,14 @@ macro(add_custom_libcxx name prefix)
ExternalProject_Add(${name} ExternalProject_Add(${name}
PREFIX ${prefix} PREFIX ${prefix}
SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH} SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH}
CMAKE_ARGS -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER} CMAKE_ARGS -DCMAKE_MAKE_PROGRAM:STRING=${CMAKE_MAKE_PROGRAM}
-DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_COMPILER} -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}
-DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}
-DCMAKE_C_FLAGS=${LIBCXX_CFLAGS} -DCMAKE_C_FLAGS=${LIBCXX_CFLAGS}
-DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS} -DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS}
-DCMAKE_BUILD_TYPE=Release -DCMAKE_BUILD_TYPE=Release
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-DLLVM_PATH=${LLVM_MAIN_SRC_DIR}
LOG_BUILD 1 LOG_BUILD 1
LOG_CONFIGURE 1 LOG_CONFIGURE 1
LOG_INSTALL 1 LOG_INSTALL 1
@ -309,3 +315,24 @@ macro(add_custom_libcxx name prefix)
DEPENDS ${LIBCXX_DEPS} DEPENDS ${LIBCXX_DEPS}
) )
endmacro() endmacro()
function(rt_externalize_debuginfo name)
if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO)
return()
endif()
if(APPLE)
if(CMAKE_CXX_FLAGS MATCHES "-flto"
OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")
set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)
set_property(TARGET ${name} APPEND_STRING PROPERTY
LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}")
endif()
add_custom_command(TARGET ${name} POST_BUILD
COMMAND xcrun dsymutil $<TARGET_FILE:${name}>
COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>)
else()
message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!")
endif()
endfunction()

View File

@ -24,19 +24,6 @@ function(translate_msvc_cflags out_flags msvc_flags)
set(${out_flags} "${clang_flags}" PARENT_SCOPE) set(${out_flags} "${clang_flags}" PARENT_SCOPE)
endfunction() endfunction()
if (APPLE)
# On Darwin if /usr/include doesn't exist, the user probably has Xcode but not
# the command line tools. If this is the case, we need to find the OS X
# sysroot to pass to clang.
if(NOT EXISTS /usr/include)
execute_process(COMMAND xcodebuild -version -sdk macosx Path
OUTPUT_VARIABLE OSX_SYSROOT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}")
endif()
endif()
# Compile a source into an object file with COMPILER_RT_TEST_COMPILER using # Compile a source into an object file with COMPILER_RT_TEST_COMPILER using
# a provided compile flags and dependenices. # a provided compile flags and dependenices.
# clang_compile(<object> <source> # clang_compile(<object> <source>

View File

@ -46,6 +46,11 @@ endfunction()
# This function takes an OS and a list of architectures and identifies the # This function takes an OS and a list of architectures and identifies the
# subset of the architectures list that the installed toolchain can target. # subset of the architectures list that the installed toolchain can target.
function(darwin_test_archs os valid_archs) function(darwin_test_archs os valid_archs)
if(${valid_archs})
message(STATUS "Using cached valid architectures for ${os}.")
return()
endif()
set(archs ${ARGN}) set(archs ${ARGN})
message(STATUS "Finding valid architectures for ${os}...") message(STATUS "Finding valid architectures for ${os}...")
set(SIMPLE_CPP ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.cpp) set(SIMPLE_CPP ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.cpp)
@ -73,15 +78,20 @@ function(darwin_test_archs os valid_archs)
OUTPUT_VARIABLE TEST_OUTPUT) OUTPUT_VARIABLE TEST_OUTPUT)
if(${CAN_TARGET_${os}_${arch}}) if(${CAN_TARGET_${os}_${arch}})
list(APPEND working_archs ${arch}) list(APPEND working_archs ${arch})
else()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Testing compiler for supporting ${os}-${arch}:\n"
"${TEST_OUTPUT}\n")
endif() endif()
endforeach() endforeach()
set(${valid_archs} ${working_archs} PARENT_SCOPE) set(${valid_archs} ${working_archs}
CACHE STRING "List of valid architectures for platform ${os}.")
endfunction() endfunction()
# This function checks the host cpusubtype to see if it is post-haswell. Haswell # This function checks the host cpusubtype to see if it is post-haswell. Haswell
# and later machines can run x86_64h binaries. Haswell is cpusubtype 8. # and later machines can run x86_64h binaries. Haswell is cpusubtype 8.
function(darwin_filter_host_archs input output) function(darwin_filter_host_archs input output)
list_union(tmp_var DARWIN_osx_ARCHS ${input}) list_intersect(tmp_var DARWIN_osx_ARCHS ${input})
execute_process( execute_process(
COMMAND sysctl hw.cpusubtype COMMAND sysctl hw.cpusubtype
OUTPUT_VARIABLE SUBTYPE) OUTPUT_VARIABLE SUBTYPE)
@ -159,11 +169,43 @@ macro(darwin_add_builtin_library name suffix)
"PARENT_TARGET;OS;ARCH" "PARENT_TARGET;OS;ARCH"
"SOURCES;CFLAGS;DEFS" "SOURCES;CFLAGS;DEFS"
${ARGN}) ${ARGN})
# --- Workaround ---
# The REF_OS variable was introduced to workaround linking problems when
# compiler-rt is build for the iOS simulator.
#
# Without this workaround, trying to link compiler-rt into an executable for
# the iOS simulator would produce an error like
#
# ld: warning: URGENT: building for iOS simulator, but linking in object
# file built for OSX. Note: This will be an error in the future.
#
# The underlying reason is that the iOS simulator specific configuration is
# stored in variables named like DARWIN_iossim_SYSROOT and not
# DARWIN_macho_embedded_SYSROOT. Thus, with the current setup, compiler-rt
# would be compiled against the OS X SDK and not the iPhone Simulator SDK.
#
# As a workaround we manually override macho_embedded with iossim when
# accessing the DARWIN_*_SYSROOT and DARWIN_*_BUILTIN_MIN_VER_FLAG variables.
#
# This workaround probably break builds of compiler-rt for the watchOS and
# tvOS simulators (if they weren't broken already).
#
# See also rust-lang/rust#34617.
if(${LIB_OS} STREQUAL "macho_embedded")
set(REF_OS iossim)
else()
set(REF_OS ${LIB_OS})
endif()
set(libname "${name}.${suffix}_${LIB_ARCH}_${LIB_OS}") set(libname "${name}.${suffix}_${LIB_ARCH}_${LIB_OS}")
add_library(${libname} STATIC ${LIB_SOURCES}) add_library(${libname} STATIC ${LIB_SOURCES})
if(DARWIN_${LIB_OS}_SYSROOT)
set(sysroot_flag -isysroot ${DARWIN_${REF_OS}_SYSROOT})
endif()
set_target_compile_flags(${libname} set_target_compile_flags(${libname}
-isysroot ${DARWIN_${LIB_OS}_SYSROOT} ${sysroot_flag}
${DARWIN_${LIB_OS}_BUILTIN_MIN_VER_FLAG} ${DARWIN_${REF_OS}_BUILTIN_MIN_VER_FLAG}
${LIB_CFLAGS}) ${LIB_CFLAGS})
set_property(TARGET ${libname} APPEND PROPERTY set_property(TARGET ${libname} APPEND PROPERTY
COMPILE_DEFINITIONS ${LIB_DEFS}) COMPILE_DEFINITIONS ${LIB_DEFS})
@ -186,18 +228,22 @@ function(darwin_lipo_libs name)
"PARENT_TARGET;OUTPUT_DIR;INSTALL_DIR" "PARENT_TARGET;OUTPUT_DIR;INSTALL_DIR"
"LIPO_FLAGS;DEPENDS" "LIPO_FLAGS;DEPENDS"
${ARGN}) ${ARGN})
add_custom_command(OUTPUT ${LIB_OUTPUT_DIR}/lib${name}.a if(LIB_DEPENDS AND LIB_LIPO_FLAGS)
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR} add_custom_command(OUTPUT ${LIB_OUTPUT_DIR}/lib${name}.a
COMMAND lipo -output COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}
${LIB_OUTPUT_DIR}/lib${name}.a COMMAND lipo -output
-create ${LIB_LIPO_FLAGS} ${LIB_OUTPUT_DIR}/lib${name}.a
DEPENDS ${LIB_DEPENDS} -create ${LIB_LIPO_FLAGS}
) DEPENDS ${LIB_DEPENDS}
add_custom_target(${name} )
DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a) add_custom_target(${name}
add_dependencies(${LIB_PARENT_TARGET} ${name}) DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a)
install(FILES ${LIB_OUTPUT_DIR}/lib${name}.a add_dependencies(${LIB_PARENT_TARGET} ${name})
DESTINATION ${LIB_INSTALL_DIR}) install(FILES ${LIB_OUTPUT_DIR}/lib${name}.a
DESTINATION ${LIB_INSTALL_DIR})
else()
message(WARNING "Not generating lipo target for ${name} because no input libraries exist.")
endif()
endfunction() endfunction()
# Filter out generic versions of routines that are re-implemented in # Filter out generic versions of routines that are re-implemented in
@ -220,7 +266,7 @@ function(darwin_filter_builtin_sources output_var exclude_or_include excluded_li
list(FIND ${excluded_list} ${_name_we} _found) list(FIND ${excluded_list} ${_name_we} _found)
if(_found ${filter_action} ${filter_value}) if(_found ${filter_action} ${filter_value})
list(REMOVE_ITEM intermediate ${_file}) list(REMOVE_ITEM intermediate ${_file})
elseif(${_file} MATCHES ".*/.*\\.S") elseif(${_file} MATCHES ".*/.*\\.S" OR ${_file} MATCHES ".*/.*\\.c")
get_filename_component(_name ${_file} NAME) get_filename_component(_name ${_file} NAME)
string(REPLACE ".S" ".c" _cname "${_name}") string(REPLACE ".S" ".c" _cname "${_name}")
list(REMOVE_ITEM intermediate ${_cname}) list(REMOVE_ITEM intermediate ${_cname})
@ -230,11 +276,18 @@ function(darwin_filter_builtin_sources output_var exclude_or_include excluded_li
endfunction() endfunction()
function(darwin_add_eprintf_library) function(darwin_add_eprintf_library)
cmake_parse_arguments(LIB
""
""
"CFLAGS"
${ARGN})
add_library(clang_rt.eprintf STATIC eprintf.c) add_library(clang_rt.eprintf STATIC eprintf.c)
set_target_compile_flags(clang_rt.eprintf set_target_compile_flags(clang_rt.eprintf
-isysroot ${DARWIN_osx_SYSROOT} -isysroot ${DARWIN_osx_SYSROOT}
${DARWIN_osx_BUILTIN_MIN_VER_FLAG} ${DARWIN_osx_BUILTIN_MIN_VER_FLAG}
-arch i386) -arch i386
${LIB_CFLAGS})
set_target_properties(clang_rt.eprintf PROPERTIES set_target_properties(clang_rt.eprintf PROPERTIES
OUTPUT_NAME clang_rt.eprintf${COMPILER_RT_OS_SUFFIX}) OUTPUT_NAME clang_rt.eprintf${COMPILER_RT_OS_SUFFIX})
set_target_properties(clang_rt.eprintf PROPERTIES set_target_properties(clang_rt.eprintf PROPERTIES
@ -251,24 +304,17 @@ endfunction()
macro(darwin_add_builtin_libraries) macro(darwin_add_builtin_libraries)
set(DARWIN_EXCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Darwin-excludes) set(DARWIN_EXCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Darwin-excludes)
if(CMAKE_CONFIGURATION_TYPES) set(CFLAGS "-fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer")
foreach(type ${CMAKE_CONFIGURATION_TYPES}) set(CMAKE_C_FLAGS "")
set(CMAKE_C_FLAGS_${type} -O3) set(CMAKE_CXX_FLAGS "")
set(CMAKE_CXX_FLAGS_${type} -O3) set(CMAKE_ASM_FLAGS "")
endforeach()
else()
set(CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE} -O3)
endif()
set(CMAKE_C_FLAGS "-fPIC -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer")
set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS})
set(PROFILE_SOURCES ../profile/InstrProfiling set(PROFILE_SOURCES ../profile/InstrProfiling
../profile/InstrProfilingBuffer ../profile/InstrProfilingBuffer
../profile/InstrProfilingPlatformDarwin) ../profile/InstrProfilingPlatformDarwin
../profile/InstrProfilingWriter)
foreach (os ${ARGN}) foreach (os ${ARGN})
list_union(DARWIN_BUILTIN_ARCHS DARWIN_${os}_ARCHS BUILTIN_SUPPORTED_ARCH) list_intersect(DARWIN_BUILTIN_ARCHS DARWIN_${os}_ARCHS BUILTIN_SUPPORTED_ARCH)
foreach (arch ${DARWIN_BUILTIN_ARCHS}) foreach (arch ${DARWIN_BUILTIN_ARCHS})
darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS
OS ${os} OS ${os}
@ -283,7 +329,7 @@ macro(darwin_add_builtin_libraries)
OS ${os} OS ${os}
ARCH ${arch} ARCH ${arch}
SOURCES ${filtered_sources} SOURCES ${filtered_sources}
CFLAGS -arch ${arch} CFLAGS ${CFLAGS} -arch ${arch}
PARENT_TARGET builtins) PARENT_TARGET builtins)
endforeach() endforeach()
@ -306,7 +352,7 @@ macro(darwin_add_builtin_libraries)
OS ${os} OS ${os}
ARCH ${arch} ARCH ${arch}
SOURCES ${filtered_sources} ${PROFILE_SOURCES} SOURCES ${filtered_sources} ${PROFILE_SOURCES}
CFLAGS -arch ${arch} -mkernel CFLAGS ${CFLAGS} -arch ${arch} -mkernel
DEFS KERNEL_USE DEFS KERNEL_USE
PARENT_TARGET builtins) PARENT_TARGET builtins)
endforeach() endforeach()
@ -323,7 +369,7 @@ macro(darwin_add_builtin_libraries)
endif() endif()
endforeach() endforeach()
darwin_add_eprintf_library() darwin_add_eprintf_library(CFLAGS ${CFLAGS})
# We put the x86 sim slices into the archives for their base OS # We put the x86 sim slices into the archives for their base OS
foreach (os ${ARGN}) foreach (os ${ARGN})
@ -339,96 +385,99 @@ macro(darwin_add_builtin_libraries)
darwin_add_embedded_builtin_libraries() darwin_add_embedded_builtin_libraries()
endmacro() endmacro()
function(darwin_add_embedded_builtin_libraries) macro(darwin_add_embedded_builtin_libraries)
set(MACHO_SYM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/macho_embedded) # this is a hacky opt-out. If you can't target both intel and arm
if(CMAKE_CONFIGURATION_TYPES) # architectures we bail here.
foreach(type ${CMAKE_CONFIGURATION_TYPES})
set(CMAKE_C_FLAGS_${type} -Oz)
set(CMAKE_CXX_FLAGS_${type} -Oz)
endforeach()
else()
set(CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE} -Oz)
endif()
set(CMAKE_C_FLAGS "-Wall -fomit-frame-pointer -ffreestanding")
set(CMAKE_CXX_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS})
set(SOFT_FLOAT_FLAG -mfloat-abi=soft)
set(HARD_FLOAT_FLAG -mfloat-abi=hard)
set(PIC_FLAG_ -fPIC)
set(STATIC_FLAG -static)
set(DARWIN_macho_embedded_ARCHS armv6m armv7m armv7em armv7 i386 x86_64)
set(DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR
${COMPILER_RT_OUTPUT_DIR}/lib/macho_embedded)
set(DARWIN_macho_embedded_LIBRARY_INSTALL_DIR
${COMPILER_RT_INSTALL_PATH}/lib/macho_embedded)
set(CFLAGS_armv7 "-target thumbv7-apple-darwin-eabi")
set(CFLAGS_armv7em "-target thumbv7-apple-darwin-eabi")
set(CFLAGS_armv7m "-target thumbv7-apple-darwin-eabi")
set(CFLAGS_i386 "-march=pentium")
set(DARWIN_SOFT_FLOAT_ARCHS armv6m armv7m armv7em armv7) set(DARWIN_SOFT_FLOAT_ARCHS armv6m armv7m armv7em armv7)
set(DARWIN_HARD_FLOAT_ARCHS armv7em armv7 i386 x86_64) set(DARWIN_HARD_FLOAT_ARCHS armv7em armv7)
if(COMPILER_RT_SUPPORTED_ARCH MATCHES ".*armv.*")
darwin_read_list_from_file(common_FUNCTIONS ${MACHO_SYM_DIR}/common.txt) list(FIND COMPILER_RT_SUPPORTED_ARCH i386 i386_idx)
darwin_read_list_from_file(thumb2_FUNCTIONS ${MACHO_SYM_DIR}/thumb2.txt) if(i386_idx GREATER -1)
darwin_read_list_from_file(thumb2_64_FUNCTIONS ${MACHO_SYM_DIR}/thumb2-64.txt) list(APPEND DARWIN_HARD_FLOAT_ARCHS i386)
darwin_read_list_from_file(arm_FUNCTIONS ${MACHO_SYM_DIR}/arm.txt)
darwin_read_list_from_file(i386_FUNCTIONS ${MACHO_SYM_DIR}/i386.txt)
set(armv6m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS})
set(armv7m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
set(armv7em_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
set(armv7_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS} ${thumb2_64_FUNCTIONS})
set(i386_FUNCTIONS ${common_FUNCTIONS} ${i386_FUNCTIONS})
set(x86_64_FUNCTIONS ${common_FUNCTIONS})
foreach(arch ${DARWIN_macho_embedded_ARCHS})
darwin_filter_builtin_sources(${arch}_filtered_sources
INCLUDE ${arch}_FUNCTIONS
${${arch}_SOURCES})
if(NOT ${arch}_filtered_sources)
message("${arch}_SOURCES: ${${arch}_SOURCES}")
message("${arch}_FUNCTIONS: ${${arch}_FUNCTIONS}")
message(FATAL_ERROR "Empty filtered sources!")
endif() endif()
endforeach()
foreach(float_type SOFT HARD) list(FIND COMPILER_RT_SUPPORTED_ARCH x86_64 x86_64_idx)
foreach(type PIC STATIC) if(x86_64_idx GREATER -1)
string(TOLOWER "${float_type}_${type}" lib_suffix) list(APPEND DARWIN_HARD_FLOAT_ARCHS x86_64)
foreach(arch ${DARWIN_${float_type}_FLOAT_ARCHS}) endif()
set(DARWIN_macho_embedded_SYSROOT ${DARWIN_osx_SYSROOT})
set(DARWIN_macho_embedded_BUILTIN_MIN_VER_FLAG ${DARWIN_osx_BUILTIN_MIN_VER_FLAG}) set(MACHO_SYM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/macho_embedded)
set(float_flag)
if(${arch} MATCHES "^arm") set(CFLAGS "-Oz -Wall -fomit-frame-pointer -ffreestanding")
set(DARWIN_macho_embedded_SYSROOT ${DARWIN_ios_SYSROOT}) set(CMAKE_C_FLAGS "")
# x86 targets are hard float by default, but the complain about the set(CMAKE_CXX_FLAGS "")
# float ABI flag, so don't pass it unless we're targeting arm. set(CMAKE_ASM_FLAGS "")
set(float_flag ${${float_type}_FLOAT_FLAG})
endif() set(SOFT_FLOAT_FLAG -mfloat-abi=soft)
darwin_add_builtin_library(clang_rt ${lib_suffix} set(HARD_FLOAT_FLAG -mfloat-abi=hard)
OS macho_embedded
ARCH ${arch} set(ENABLE_PIC Off)
SOURCES ${${arch}_filtered_sources} set(PIC_FLAG -fPIC)
CFLAGS -arch ${arch} ${${type}_FLAG} ${float_flag} ${CFLAGS_${arch}} set(STATIC_FLAG -static)
PARENT_TARGET builtins)
endforeach() set(DARWIN_macho_embedded_ARCHS armv6m armv7m armv7em armv7 i386 x86_64)
foreach(lib ${macho_embedded_${lib_suffix}_libs})
set_target_properties(${lib} PROPERTIES LINKER_LANGUAGE C) set(DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR
endforeach() ${COMPILER_RT_OUTPUT_DIR}/lib/macho_embedded)
darwin_lipo_libs(clang_rt.${lib_suffix} set(DARWIN_macho_embedded_LIBRARY_INSTALL_DIR
PARENT_TARGET builtins ${COMPILER_RT_INSTALL_PATH}/lib/macho_embedded)
LIPO_FLAGS ${macho_embedded_${lib_suffix}_lipo_flags}
DEPENDS ${macho_embedded_${lib_suffix}_libs} set(CFLAGS_armv7 "-target thumbv7-apple-darwin-eabi")
OUTPUT_DIR ${DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR} set(CFLAGS_i386 "-march=pentium")
INSTALL_DIR ${DARWIN_macho_embedded_LIBRARY_INSTALL_DIR})
darwin_read_list_from_file(common_FUNCTIONS ${MACHO_SYM_DIR}/common.txt)
darwin_read_list_from_file(thumb2_FUNCTIONS ${MACHO_SYM_DIR}/thumb2.txt)
darwin_read_list_from_file(thumb2_64_FUNCTIONS ${MACHO_SYM_DIR}/thumb2-64.txt)
darwin_read_list_from_file(arm_FUNCTIONS ${MACHO_SYM_DIR}/arm.txt)
darwin_read_list_from_file(i386_FUNCTIONS ${MACHO_SYM_DIR}/i386.txt)
set(armv6m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS})
set(armv7m_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
set(armv7em_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS})
set(armv7_FUNCTIONS ${common_FUNCTIONS} ${arm_FUNCTIONS} ${thumb2_FUNCTIONS} ${thumb2_64_FUNCTIONS})
set(i386_FUNCTIONS ${common_FUNCTIONS} ${i386_FUNCTIONS})
set(x86_64_FUNCTIONS ${common_FUNCTIONS})
foreach(arch ${DARWIN_macho_embedded_ARCHS})
darwin_filter_builtin_sources(${arch}_filtered_sources
INCLUDE ${arch}_FUNCTIONS
${${arch}_SOURCES})
if(NOT ${arch}_filtered_sources)
message("${arch}_SOURCES: ${${arch}_SOURCES}")
message("${arch}_FUNCTIONS: ${${arch}_FUNCTIONS}")
message(FATAL_ERROR "Empty filtered sources!")
endif()
endforeach() endforeach()
endforeach()
endfunction() foreach(float_type SOFT HARD)
foreach(type PIC STATIC)
string(TOLOWER "${float_type}_${type}" lib_suffix)
foreach(arch ${DARWIN_${float_type}_FLOAT_ARCHS})
set(DARWIN_macho_embedded_SYSROOT ${DARWIN_osx_SYSROOT})
set(float_flag)
if(${arch} MATCHES "^arm")
# x86 targets are hard float by default, but the complain about the
# float ABI flag, so don't pass it unless we're targeting arm.
set(float_flag ${${float_type}_FLOAT_FLAG})
endif()
darwin_add_builtin_library(clang_rt ${lib_suffix}
OS macho_embedded
ARCH ${arch}
SOURCES ${${arch}_filtered_sources}
CFLAGS ${CFLAGS} -arch ${arch} ${${type}_FLAG} ${float_flag} ${CFLAGS_${arch}}
PARENT_TARGET builtins)
endforeach()
foreach(lib ${macho_embedded_${lib_suffix}_libs})
set_target_properties(${lib} PROPERTIES LINKER_LANGUAGE C)
endforeach()
darwin_lipo_libs(clang_rt.${lib_suffix}
PARENT_TARGET builtins
LIPO_FLAGS ${macho_embedded_${lib_suffix}_lipo_flags}
DEPENDS ${macho_embedded_${lib_suffix}_libs}
OUTPUT_DIR ${DARWIN_macho_embedded_LIBRARY_OUTPUT_DIR}
INSTALL_DIR ${DARWIN_macho_embedded_LIBRARY_INSTALL_DIR})
endforeach()
endforeach()
endif()
endmacro()

View File

@ -58,7 +58,7 @@ macro(append_have_file_definition filename varname list)
list(APPEND ${list} "${varname}=${${varname}}") list(APPEND ${list} "${varname}=${${varname}}")
endmacro() endmacro()
macro(list_union output input1 input2) macro(list_intersect output input1 input2)
set(${output}) set(${output})
foreach(it ${${input1}}) foreach(it ${${input1}})
list(FIND ${input2} ${it} index) list(FIND ${input2} ${it} index)

View File

@ -27,7 +27,14 @@ check_cxx_compiler_flag("-Werror -fno-function-sections" COMPILER_RT_HAS_FNO_FUN
check_cxx_compiler_flag(-std=c++11 COMPILER_RT_HAS_STD_CXX11_FLAG) check_cxx_compiler_flag(-std=c++11 COMPILER_RT_HAS_STD_CXX11_FLAG)
check_cxx_compiler_flag(-ftls-model=initial-exec COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC) check_cxx_compiler_flag(-ftls-model=initial-exec COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC)
check_cxx_compiler_flag(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG) check_cxx_compiler_flag(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG)
check_cxx_compiler_flag(-msse3 COMPILER_RT_HAS_MSSE3_FLAG) check_cxx_compiler_flag("-Werror -msse3" COMPILER_RT_HAS_MSSE3_FLAG)
check_cxx_compiler_flag(-std=c99 COMPILER_RT_HAS_STD_C99_FLAG)
check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG)
if(NOT WIN32 AND NOT CYGWIN)
# MinGW warns if -fvisibility-inlines-hidden is used.
check_cxx_compiler_flag("-fvisibility-inlines-hidden" COMPILER_RT_HAS_FVISIBILITY_INLINES_HIDDEN_FLAG)
endif()
check_cxx_compiler_flag(/GR COMPILER_RT_HAS_GR_FLAG) check_cxx_compiler_flag(/GR COMPILER_RT_HAS_GR_FLAG)
check_cxx_compiler_flag(/GS COMPILER_RT_HAS_GS_FLAG) check_cxx_compiler_flag(/GS COMPILER_RT_HAS_GS_FLAG)
@ -61,7 +68,7 @@ check_cxx_compiler_flag(/wd4800 COMPILER_RT_HAS_WD4800_FLAG)
check_symbol_exists(__func__ "" COMPILER_RT_HAS_FUNC_SYMBOL) check_symbol_exists(__func__ "" COMPILER_RT_HAS_FUNC_SYMBOL)
# Libraries. # Libraries.
check_library_exists(c printf "" COMPILER_RT_HAS_LIBC) check_library_exists(c fopen "" COMPILER_RT_HAS_LIBC)
check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL) check_library_exists(dl dlopen "" COMPILER_RT_HAS_LIBDL)
check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT) check_library_exists(rt shm_open "" COMPILER_RT_HAS_LIBRT)
check_library_exists(m pow "" COMPILER_RT_HAS_LIBM) check_library_exists(m pow "" COMPILER_RT_HAS_LIBM)
@ -143,8 +150,11 @@ macro(detect_target_arch)
check_symbol_exists(__i386__ "" __I386) check_symbol_exists(__i386__ "" __I386)
check_symbol_exists(__mips__ "" __MIPS) check_symbol_exists(__mips__ "" __MIPS)
check_symbol_exists(__mips64__ "" __MIPS64) check_symbol_exists(__mips64__ "" __MIPS64)
check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32)
check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64)
if(__ARM) if(__ARM)
add_default_target_arch(arm) # Android shouldn't use Thumb2 instructions but can use VFP instructions.
add_default_target_arch(armhf)
elseif(__AARCH64) elseif(__AARCH64)
add_default_target_arch(aarch64) add_default_target_arch(aarch64)
elseif(__X86_64) elseif(__X86_64)
@ -157,6 +167,10 @@ macro(detect_target_arch)
add_default_target_arch(mips64) add_default_target_arch(mips64)
elseif(__MIPS) elseif(__MIPS)
add_default_target_arch(mips) add_default_target_arch(mips)
elseif(__WEBASSEMBLY32)
add_default_target_arch(wasm32)
elseif(__WEBASSEMBLY64)
add_default_target_arch(wasm64)
endif() endif()
endmacro() endmacro()
@ -191,6 +205,7 @@ elseif(NOT APPLE) # Supported archs for Apple platforms are generated later
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc")
TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN) TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN)
if(HOST_IS_BIG_ENDIAN) if(HOST_IS_BIG_ENDIAN)
test_target_arch(powerpc "" "-m32")
test_target_arch(powerpc64 "" "-m64") test_target_arch(powerpc64 "" "-m64")
else() else()
test_target_arch(powerpc64le "" "-m64") test_target_arch(powerpc64le "" "-m64")
@ -207,15 +222,21 @@ elseif(NOT APPLE) # Supported archs for Apple platforms are generated later
test_target_arch(mips "" "-mips32r2" "--target=mips-linux-gnu") test_target_arch(mips "" "-mips32r2" "--target=mips-linux-gnu")
test_target_arch(mips64 "" "-mips64r2" "--target=mips64-linux-gnu" "-mabi=n64") test_target_arch(mips64 "" "-mips64r2" "--target=mips64-linux-gnu" "-mabi=n64")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm")
if("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES "eabihf") if("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES "armv7")
test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard") test_target_arch(armv7 "" "${CMAKE_C_FLAGS}")
elseif("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES "eabihf")
test_target_arch(armhf "" "${CMAKE_C_FLAGS}")
else() else()
test_target_arch(arm "" "-march=armv7-a" "-mfloat-abi=soft") test_target_arch(arm "" "${CMAKE_C_FLAGS}")
endif() endif()
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32")
test_target_arch(aarch32 "" "-march=armv8-a") test_target_arch(aarch32 "" "-march=armv8-a")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64")
test_target_arch(aarch64 "" "-march=armv8-a") test_target_arch(aarch64 "" "-march=armv8-a")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm32")
test_target_arch(wasm32 "" "--target=wasm32-unknown-unknown")
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "wasm64")
test_target_arch(wasm64 "" "--target=wasm64-unknown-unknown")
endif() endif()
set(COMPILER_RT_OS_SUFFIX "") set(COMPILER_RT_OS_SUFFIX "")
endif() endif()
@ -250,12 +271,15 @@ function(get_target_flags_for_arch arch out_var)
endfunction() endfunction()
set(ARM64 aarch64) set(ARM64 aarch64)
set(ARM32 arm armhf) set(ARM32 arm armhf armv7)
set(X86 i386 i686) set(X86 i386 i686)
set(X86_64 x86_64) set(X86_64 x86_64)
set(MIPS32 mips mipsel) set(MIPS32 mips mipsel)
set(MIPS64 mips64 mips64el) set(MIPS64 mips64 mips64el)
set(PPC powerpc)
set(PPC64 powerpc64 powerpc64le) set(PPC64 powerpc64 powerpc64le)
set(WASM32 wasm32)
set(WASM64 wasm64)
if(APPLE) if(APPLE)
set(ARM64 arm64) set(ARM64 arm64)
@ -264,7 +288,7 @@ if(APPLE)
endif() endif()
set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} set(ALL_BUILTIN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
${MIPS32} ${MIPS64}) ${MIPS32} ${MIPS64} ${WASM32} ${WASM64} ${PPC} ${PPC64})
set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64}
${ARM32} ${ARM64} ${MIPS32} ${MIPS64}) ${ARM32} ${ARM64} ${MIPS32} ${MIPS64})
set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
@ -274,19 +298,65 @@ set(ALL_LSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64} set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64}
${MIPS32} ${MIPS64}) ${MIPS32} ${MIPS64})
set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64})
set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
${MIPS32} ${MIPS64} ${PPC64}) ${MIPS32} ${MIPS64} ${PPC64})
set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64}) set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM64})
set(ALL_CFI_SUPPORTED_ARCH ${X86} ${X86_64})
if(APPLE) if(APPLE)
include(CompilerRTDarwinUtils) include(CompilerRTDarwinUtils)
# On Darwin if /usr/include doesn't exist, the user probably has Xcode but not
# the command line tools. If this is the case, we need to find the OS X
# sysroot to pass to clang.
if(NOT EXISTS /usr/include)
execute_process(COMMAND xcodebuild -version -sdk macosx Path
OUTPUT_VARIABLE OSX_SYSROOT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(OSX_SYSROOT_FLAG "-isysroot${OSX_SYSROOT}")
endif()
option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off) option(COMPILER_RT_ENABLE_IOS "Enable building for iOS - Experimental" Off)
option(COMPILER_RT_ENABLE_WATCHOS "Enable building for watchOS - Experimental" Off)
option(COMPILER_RT_ENABLE_TVOS "Enable building for tvOS - Experimental" Off)
find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx) find_darwin_sdk_dir(DARWIN_osx_SYSROOT macosx)
find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator) find_darwin_sdk_dir(DARWIN_iossim_SYSROOT iphonesimulator)
find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos) find_darwin_sdk_dir(DARWIN_ios_SYSROOT iphoneos)
find_darwin_sdk_dir(DARWIN_watchossim_SYSROOT watchsimulator)
find_darwin_sdk_dir(DARWIN_watchos_SYSROOT watchos)
find_darwin_sdk_dir(DARWIN_tvossim_SYSROOT appletvsimulator)
find_darwin_sdk_dir(DARWIN_tvos_SYSROOT appletvos)
if(COMPILER_RT_ENABLE_IOS)
list(APPEND DARWIN_EMBEDDED_PLATFORMS ios)
set(DARWIN_ios_MIN_VER_FLAG -miphoneos-version-min)
set(DARWIN_ios_SANITIZER_MIN_VER_FLAG
${DARWIN_ios_MIN_VER_FLAG}=7.0)
set(DARWIN_ios_BUILTIN_MIN_VER 6.0)
set(DARWIN_ios_BUILTIN_MIN_VER_FLAG
${DARWIN_ios_MIN_VER_FLAG}=${DARWIN_ios_BUILTIN_MIN_VER})
endif()
if(COMPILER_RT_ENABLE_WATCHOS)
list(APPEND DARWIN_EMBEDDED_PLATFORMS watchos)
set(DARWIN_watchos_MIN_VER_FLAG -mwatchos-version-min)
set(DARWIN_watchos_SANITIZER_MIN_VER_FLAG
${DARWIN_watchos_MIN_VER_FLAG}=2.0)
set(DARWIN_watchos_BUILTIN_MIN_VER 2.0)
set(DARWIN_watchos_BUILTIN_MIN_VER_FLAG
${DARWIN_watchos_MIN_VER_FLAG}=${DARWIN_watchos_BUILTIN_MIN_VER})
endif()
if(COMPILER_RT_ENABLE_TVOS)
list(APPEND DARWIN_EMBEDDED_PLATFORMS tvos)
set(DARWIN_tvos_MIN_VER_FLAG -mtvos-version-min)
set(DARWIN_tvos_SANITIZER_MIN_VER_FLAG
${DARWIN_tvos_MIN_VER_FLAG}=9.0)
set(DARWIN_tvos_BUILTIN_MIN_VER 9.0)
set(DARWIN_tvos_BUILTIN_MIN_VER_FLAG
${DARWIN_tvos_MIN_VER_FLAG}=${DARWIN_tvos_BUILTIN_MIN_VER})
endif()
# Note: In order to target x86_64h on OS X the minimum deployment target must # Note: In order to target x86_64h on OS X the minimum deployment target must
# be 10.8 or higher. # be 10.8 or higher.
@ -311,13 +381,18 @@ if(APPLE)
# We're setting the flag manually for each target OS # We're setting the flag manually for each target OS
set(CMAKE_OSX_DEPLOYMENT_TARGET "") set(CMAKE_OSX_DEPLOYMENT_TARGET "")
set(DARWIN_COMMON_CFLAGS -stdlib=libc++) set(DARWIN_COMMON_CFLAGS -stdlib=libc++)
set(DARWIN_COMMON_LINKFLAGS set(DARWIN_COMMON_LINKFLAGS
-stdlib=libc++ -stdlib=libc++
-lc++ -lc++
-lc++abi) -lc++abi)
check_linker_flag("-fapplication-extension" COMPILER_RT_HAS_APP_EXTENSION)
if(COMPILER_RT_HAS_APP_EXTENSION)
list(APPEND DARWIN_COMMON_LINKFLAGS "-fapplication-extension")
endif()
set(DARWIN_osx_CFLAGS set(DARWIN_osx_CFLAGS
${DARWIN_COMMON_CFLAGS} ${DARWIN_COMMON_CFLAGS}
-mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION}) -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})
@ -336,7 +411,7 @@ if(APPLE)
# Figure out which arches to use for each OS # Figure out which arches to use for each OS
darwin_get_toolchain_supported_archs(toolchain_arches) darwin_get_toolchain_supported_archs(toolchain_arches)
message(STATUS "Toolchain supported arches: ${toolchain_arches}") message(STATUS "Toolchain supported arches: ${toolchain_arches}")
if(NOT MACOSX_VERSION_MIN_FLAG) if(NOT MACOSX_VERSION_MIN_FLAG)
darwin_test_archs(osx darwin_test_archs(osx
DARWIN_osx_ARCHS DARWIN_osx_ARCHS
@ -363,98 +438,102 @@ if(APPLE)
list(APPEND BUILTIN_SUPPORTED_OS 10.4) list(APPEND BUILTIN_SUPPORTED_OS 10.4)
endif() endif()
if(DARWIN_iossim_SYSROOT) foreach(platform ${DARWIN_EMBEDDED_PLATFORMS})
set(DARWIN_iossim_CFLAGS if(DARWIN_${platform}sim_SYSROOT)
${DARWIN_COMMON_CFLAGS} set(DARWIN_${platform}sim_CFLAGS
-mios-simulator-version-min=7.0 ${DARWIN_COMMON_CFLAGS}
-isysroot ${DARWIN_iossim_SYSROOT}) ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
set(DARWIN_iossim_LINKFLAGS -isysroot ${DARWIN_iossim_SYSROOT})
${DARWIN_COMMON_LINKFLAGS} set(DARWIN_${platform}sim_LINKFLAGS
-mios-simulator-version-min=7.0 ${DARWIN_COMMON_LINKFLAGS}
-isysroot ${DARWIN_iossim_SYSROOT}) ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
set(DARWIN_iossim_BUILTIN_MIN_VER 6.0) -isysroot ${DARWIN_${platform}sim_SYSROOT})
set(DARWIN_iossim_BUILTIN_MIN_VER_FLAG set(DARWIN_${platform}sim_BUILTIN_MIN_VER
-mios-simulator-version-min=${DARWIN_iossim_BUILTIN_MIN_VER}) ${DARWIN_${platform}_BUILTIN_MIN_VER})
set(DARWIN_${platform}sim_BUILTIN_MIN_VER_FLAG
${DARWIN_${platform}_BUILTIN_MIN_VER_FLAG})
set(DARWIN_iossim_SKIP_CC_KEXT On) set(DARWIN_${platform}sim_SKIP_CC_KEXT On)
darwin_test_archs(iossim darwin_test_archs(${platform}sim
DARWIN_iossim_ARCHS DARWIN_${platform}sim_ARCHS
${toolchain_arches}) ${toolchain_arches})
message(STATUS "iOS Simulator supported arches: ${DARWIN_iossim_ARCHS}") message(STATUS "${platform} Simulator supported arches: ${DARWIN_${platform}sim_ARCHS}")
if(DARWIN_iossim_ARCHS) if(DARWIN_iossim_ARCHS)
list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim) list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform}sim)
list(APPEND BUILTIN_SUPPORTED_OS ${platform}sim)
list(APPEND PROFILE_SUPPORTED_OS ${platform}sim)
endif()
foreach(arch ${DARWIN_${platform}sim_ARCHS})
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
set(CAN_TARGET_${arch} 1)
endforeach()
endif() endif()
foreach(arch ${DARWIN_iossim_ARCHS})
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
set(CAN_TARGET_${arch} 1)
endforeach()
endif()
if(DARWIN_ios_SYSROOT AND COMPILER_RT_ENABLE_IOS) if(DARWIN_${platform}_SYSROOT)
set(DARWIN_ios_CFLAGS set(DARWIN_${platform}_CFLAGS
${DARWIN_COMMON_CFLAGS} ${DARWIN_COMMON_CFLAGS}
-miphoneos-version-min=7.0 ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
-isysroot ${DARWIN_ios_SYSROOT}) -isysroot ${DARWIN_${platform}_SYSROOT})
set(DARWIN_ios_LINKFLAGS set(DARWIN_${platform}_LINKFLAGS
${DARWIN_COMMON_LINKFLAGS} ${DARWIN_COMMON_LINKFLAGS}
-miphoneos-version-min=7.0 ${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
-isysroot ${DARWIN_ios_SYSROOT}) -isysroot ${DARWIN_${platform}_SYSROOT})
set(DARWIN_ios_BUILTIN_MIN_VER 6.0)
set(DARWIN_ios_BUILTIN_MIN_VER_FLAG
-miphoneos-version-min=${DARWIN_ios_BUILTIN_MIN_VER})
darwin_test_archs(ios darwin_test_archs(${platform}
DARWIN_ios_ARCHS DARWIN_${platform}_ARCHS
${toolchain_arches}) ${toolchain_arches})
message(STATUS "iOS supported arches: ${DARWIN_ios_ARCHS}") message(STATUS "${platform} supported arches: ${DARWIN_${platform}_ARCHS}")
if(DARWIN_ios_ARCHS) if(DARWIN_${platform}_ARCHS)
list(APPEND SANITIZER_COMMON_SUPPORTED_OS ios) list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform})
list(APPEND BUILTIN_SUPPORTED_OS ios) list(APPEND BUILTIN_SUPPORTED_OS ${platform})
list(APPEND PROFILE_SUPPORTED_OS ios) list(APPEND PROFILE_SUPPORTED_OS ${platform})
list(APPEND BUILTIN_SUPPORTED_OS iossim) endif()
foreach(arch ${DARWIN_${platform}_ARCHS})
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
set(CAN_TARGET_${arch} 1)
endforeach()
endif() endif()
foreach(arch ${DARWIN_ios_ARCHS}) endforeach()
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
set(CAN_TARGET_${arch} 1)
endforeach()
endif()
endif() endif()
# for list_union # for list_intersect
include(CompilerRTUtils) include(CompilerRTUtils)
list_union(BUILTIN_SUPPORTED_ARCH ALL_BUILTIN_SUPPORTED_ARCH toolchain_arches) list_intersect(BUILTIN_SUPPORTED_ARCH ALL_BUILTIN_SUPPORTED_ARCH toolchain_arches)
list_union(SANITIZER_COMMON_SUPPORTED_ARCH list_intersect(SANITIZER_COMMON_SUPPORTED_ARCH
ALL_SANITIZER_COMMON_SUPPORTED_ARCH ALL_SANITIZER_COMMON_SUPPORTED_ARCH
COMPILER_RT_SUPPORTED_ARCH COMPILER_RT_SUPPORTED_ARCH
) )
set(LSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}) set(LSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH})
set(UBSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH}) set(UBSAN_COMMON_SUPPORTED_ARCH ${SANITIZER_COMMON_SUPPORTED_ARCH})
list_union(ASAN_SUPPORTED_ARCH list_intersect(ASAN_SUPPORTED_ARCH
ALL_ASAN_SUPPORTED_ARCH ALL_ASAN_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH) SANITIZER_COMMON_SUPPORTED_ARCH)
list_union(DFSAN_SUPPORTED_ARCH list_intersect(DFSAN_SUPPORTED_ARCH
ALL_DFSAN_SUPPORTED_ARCH ALL_DFSAN_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH) SANITIZER_COMMON_SUPPORTED_ARCH)
list_union(LSAN_SUPPORTED_ARCH list_intersect(LSAN_SUPPORTED_ARCH
ALL_LSAN_SUPPORTED_ARCH ALL_LSAN_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH) SANITIZER_COMMON_SUPPORTED_ARCH)
list_union(MSAN_SUPPORTED_ARCH list_intersect(MSAN_SUPPORTED_ARCH
ALL_MSAN_SUPPORTED_ARCH ALL_MSAN_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH) SANITIZER_COMMON_SUPPORTED_ARCH)
list_union(PROFILE_SUPPORTED_ARCH list_intersect(PROFILE_SUPPORTED_ARCH
ALL_PROFILE_SUPPORTED_ARCH ALL_PROFILE_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH) SANITIZER_COMMON_SUPPORTED_ARCH)
list_union(TSAN_SUPPORTED_ARCH list_intersect(TSAN_SUPPORTED_ARCH
ALL_TSAN_SUPPORTED_ARCH ALL_TSAN_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH) SANITIZER_COMMON_SUPPORTED_ARCH)
list_union(UBSAN_SUPPORTED_ARCH list_intersect(UBSAN_SUPPORTED_ARCH
ALL_UBSAN_SUPPORTED_ARCH ALL_UBSAN_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH) SANITIZER_COMMON_SUPPORTED_ARCH)
list_union(SAFESTACK_SUPPORTED_ARCH list_intersect(SAFESTACK_SUPPORTED_ARCH
ALL_SAFESTACK_SUPPORTED_ARCH ALL_SAFESTACK_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH) SANITIZER_COMMON_SUPPORTED_ARCH)
list_intersect(CFI_SUPPORTED_ARCH
ALL_CFI_SUPPORTED_ARCH
SANITIZER_COMMON_SUPPORTED_ARCH)
else() else()
# Architectures supported by compiler-rt libraries. # Architectures supported by compiler-rt libraries.
filter_available_targets(BUILTIN_SUPPORTED_ARCH filter_available_targets(BUILTIN_SUPPORTED_ARCH
@ -476,6 +555,7 @@ else()
filter_available_targets(UBSAN_SUPPORTED_ARCH ${ALL_UBSAN_SUPPORTED_ARCH}) filter_available_targets(UBSAN_SUPPORTED_ARCH ${ALL_UBSAN_SUPPORTED_ARCH})
filter_available_targets(SAFESTACK_SUPPORTED_ARCH filter_available_targets(SAFESTACK_SUPPORTED_ARCH
${ALL_SAFESTACK_SUPPORTED_ARCH}) ${ALL_SAFESTACK_SUPPORTED_ARCH})
filter_available_targets(CFI_SUPPORTED_ARCH ${ALL_CFI_SUPPORTED_ARCH})
endif() endif()
message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}") message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}")
@ -538,26 +618,19 @@ else()
endif() endif()
if (PROFILE_SUPPORTED_ARCH AND if (PROFILE_SUPPORTED_ARCH AND
OS_NAME MATCHES "Darwin|Linux|FreeBSD") OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows")
set(COMPILER_RT_HAS_PROFILE TRUE) set(COMPILER_RT_HAS_PROFILE TRUE)
else() else()
set(COMPILER_RT_HAS_PROFILE FALSE) set(COMPILER_RT_HAS_PROFILE FALSE)
endif() endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND if (COMPILER_RT_HAS_SANITIZER_COMMON AND TSAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Linux|FreeBSD") OS_NAME MATCHES "Darwin|Linux|FreeBSD")
set(COMPILER_RT_HAS_TSAN TRUE) set(COMPILER_RT_HAS_TSAN TRUE)
else() else()
set(COMPILER_RT_HAS_TSAN FALSE) set(COMPILER_RT_HAS_TSAN FALSE)
endif() endif()
if(APPLE)
option(COMPILER_RT_ENABLE_TSAN_OSX "Enable building TSan for OS X - Experimental" Off)
if(COMPILER_RT_ENABLE_TSAN_OSX)
set(COMPILER_RT_HAS_TSAN TRUE)
endif()
endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND
OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows") OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows")
set(COMPILER_RT_HAS_UBSAN TRUE) set(COMPILER_RT_HAS_UBSAN TRUE)
@ -565,17 +638,16 @@ else()
set(COMPILER_RT_HAS_UBSAN FALSE) set(COMPILER_RT_HAS_UBSAN FALSE)
endif() endif()
# -msse3 flag is not valid for Mips therefore clang gives a warning
# message with -msse3. But check_c_compiler_flags() checks only for
# compiler error messages. Therefore COMPILER_RT_HAS_MSSE3_FLAG turns out to be
# true on Mips, so we make it false here.
if("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "mips")
set(COMPILER_RT_HAS_MSSE3_FLAG FALSE)
endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND
OS_NAME MATCHES "Darwin|Linux|FreeBSD") OS_NAME MATCHES "Darwin|Linux|FreeBSD")
set(COMPILER_RT_HAS_SAFESTACK TRUE) set(COMPILER_RT_HAS_SAFESTACK TRUE)
else() else()
set(COMPILER_RT_HAS_SAFESTACK FALSE) set(COMPILER_RT_HAS_SAFESTACK FALSE)
endif() endif()
if (COMPILER_RT_HAS_SANITIZER_COMMON AND CFI_SUPPORTED_ARCH AND
OS_NAME MATCHES "Linux")
set(COMPILER_RT_HAS_CFI TRUE)
else()
set(COMPILER_RT_HAS_CFI FALSE)
endif()

View File

@ -125,9 +125,11 @@ extern "C" {
// to know what is being passed to libc functions, e.g. memcmp. // to know what is being passed to libc functions, e.g. memcmp.
// FIXME: implement more hooks. // FIXME: implement more hooks.
void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1, void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
const void *s2, size_t n); const void *s2, size_t n, int result);
void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1, void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
const char *s2, size_t n); const char *s2, size_t n, int result);
void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
const char *s2, int result);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View File

@ -41,6 +41,13 @@ extern "C" {
// Some of the entries in *data will be zero. // Some of the entries in *data will be zero.
uintptr_t __sanitizer_get_coverage_guards(uintptr_t **data); uintptr_t __sanitizer_get_coverage_guards(uintptr_t **data);
// Set *data to the growing buffer with covered PCs and return the size
// of the buffer. The entries are never zero.
// When only unique pcs are collected, the size is equal to
// __sanitizer_get_total_unique_coverage.
// WARNING: EXPERIMENTAL API.
uintptr_t __sanitizer_get_coverage_pc_buffer(uintptr_t **data);
// The coverage instrumentation may optionally provide imprecise counters. // The coverage instrumentation may optionally provide imprecise counters.
// Rather than exposing the counter values to the user we instead map // Rather than exposing the counter values to the user we instead map
// the counters to a bitset. // the counters to a bitset.

View File

@ -19,8 +19,6 @@ if(COMPILER_RT_BUILD_SANITIZERS)
add_subdirectory(ubsan) add_subdirectory(ubsan)
endif() endif()
add_subdirectory(cfi)
if(COMPILER_RT_HAS_ASAN) if(COMPILER_RT_HAS_ASAN)
add_subdirectory(asan) add_subdirectory(asan)
endif() endif()
@ -45,4 +43,8 @@ if(COMPILER_RT_BUILD_SANITIZERS)
if(COMPILER_RT_HAS_SAFESTACK) if(COMPILER_RT_HAS_SAFESTACK)
add_subdirectory(safestack) add_subdirectory(safestack)
endif() endif()
if(COMPILER_RT_HAS_CFI)
add_subdirectory(cfi)
endif()
endif() endif()

View File

@ -0,0 +1 @@
BasedOnStyle: Google

View File

@ -23,4 +23,4 @@ from the root of your CMake build tree:
make check-asan make check-asan
For more instructions see: For more instructions see:
http://code.google.com/p/address-sanitizer/wiki/HowToBuild https://github.com/google/sanitizers/wiki/AddressSanitizerHowToBuild

View File

@ -61,11 +61,6 @@ static struct AsanDeactivatedFlags {
parser.ParseString(env); parser.ParseString(env);
} }
// Override from getprop asan.options.
char buf[100];
GetExtraActivationFlags(buf, sizeof(buf));
parser.ParseString(buf);
SetVerbosity(cf.verbosity); SetVerbosity(cf.verbosity);
if (Verbosity()) ReportUnrecognizedFlags(); if (Verbosity()) ReportUnrecognizedFlags();

View File

@ -116,14 +116,6 @@ void InitializeFlags() {
ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
#endif #endif
// Let activation flags override current settings. On Android they come
// from a system property. On other platforms this is no-op.
if (!flags()->start_deactivated) {
char buf[100];
GetExtraActivationFlags(buf, sizeof(buf));
asan_parser.ParseString(buf);
}
SetVerbosity(common_flags()->verbosity); SetVerbosity(common_flags()->verbosity);
// TODO(eugenis): dump all flags at verbosity>=2? // TODO(eugenis): dump all flags at verbosity>=2?

View File

@ -44,9 +44,6 @@ ASAN_FLAG(
"to find more errors.") "to find more errors.")
ASAN_FLAG(bool, replace_intrin, true, ASAN_FLAG(bool, replace_intrin, true,
"If set, uses custom wrappers for memset/memcpy/memmove intinsics.") "If set, uses custom wrappers for memset/memcpy/memmove intinsics.")
ASAN_FLAG(bool, mac_ignore_invalid_free, false,
"Ignore invalid free() calls to work around some bugs. Used on OS X "
"only.")
ASAN_FLAG(bool, detect_stack_use_after_return, false, ASAN_FLAG(bool, detect_stack_use_after_return, false,
"Enables stack-use-after-return checking at run-time.") "Enables stack-use-after-return checking at run-time.")
ASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway. ASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway.
@ -75,6 +72,7 @@ ASAN_FLAG(bool, check_malloc_usable_size, true,
"295.*.") "295.*.")
ASAN_FLAG(bool, unmap_shadow_on_exit, false, ASAN_FLAG(bool, unmap_shadow_on_exit, false,
"If set, explicitly unmaps the (huge) shadow at exit.") "If set, explicitly unmaps the (huge) shadow at exit.")
ASAN_FLAG(bool, protect_shadow_gap, true, "If set, mprotect the shadow gap")
ASAN_FLAG(bool, print_stats, false, ASAN_FLAG(bool, print_stats, false,
"Print various statistics after printing an error message or if " "Print various statistics after printing an error message or if "
"atexit=1.") "atexit=1.")
@ -98,8 +96,8 @@ ASAN_FLAG(bool, poison_array_cookie, true,
"Poison (or not) the array cookie after operator new[].") "Poison (or not) the array cookie after operator new[].")
// Turn off alloc/dealloc mismatch checker on Mac and Windows for now. // Turn off alloc/dealloc mismatch checker on Mac and Windows for now.
// https://code.google.com/p/address-sanitizer/issues/detail?id=131 // https://github.com/google/sanitizers/issues/131
// https://code.google.com/p/address-sanitizer/issues/detail?id=309 // https://github.com/google/sanitizers/issues/309
// TODO(glider,timurrrr): Fix known issues and enable this back. // TODO(glider,timurrrr): Fix known issues and enable this back.
ASAN_FLAG(bool, alloc_dealloc_mismatch, ASAN_FLAG(bool, alloc_dealloc_mismatch,
(SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0), (SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0),
@ -125,8 +123,8 @@ ASAN_FLAG(
"The bigger the value the harder we try.") "The bigger the value the harder we try.")
ASAN_FLAG( ASAN_FLAG(
bool, detect_container_overflow, true, bool, detect_container_overflow, true,
"If true, honor the container overflow annotations. " "If true, honor the container overflow annotations. See "
"See https://code.google.com/p/address-sanitizer/wiki/ContainerOverflow") "https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow")
ASAN_FLAG(int, detect_odr_violation, 2, ASAN_FLAG(int, detect_odr_violation, 2,
"If >=2, detect violation of One-Definition-Rule (ODR); " "If >=2, detect violation of One-Definition-Rule (ODR); "
"If ==1, detect ODR-violation only if the two variables " "If ==1, detect ODR-violation only if the two variables "
@ -134,3 +132,6 @@ ASAN_FLAG(int, detect_odr_violation, 2,
ASAN_FLAG(bool, dump_instruction_bytes, false, ASAN_FLAG(bool, dump_instruction_bytes, false,
"If true, dump 16 bytes starting at the instruction that caused SEGV") "If true, dump 16 bytes starting at the instruction that caused SEGV")
ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.") ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
ASAN_FLAG(bool, halt_on_error, true,
"Crash the program after printing the first error report "
"(WARNING: USE AT YOUR OWN RISK!)")

View File

@ -75,7 +75,7 @@ struct AsanInterceptorContext {
} \ } \
if (!suppressed) { \ if (!suppressed) { \
GET_CURRENT_PC_BP_SP; \ GET_CURRENT_PC_BP_SP; \
__asan_report_error(pc, bp, sp, __bad, isWrite, __size, 0); \ ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false);\
} \ } \
} \ } \
} while (0) } while (0)
@ -178,7 +178,7 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
} while (false) } while (false)
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name) #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
// Strict init-order checking is dlopen-hostile: // Strict init-order checking is dlopen-hostile:
// https://code.google.com/p/address-sanitizer/issues/detail?id=178 // https://github.com/google/sanitizers/issues/178
#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
if (flags()->strict_init_order) { \ if (flags()->strict_init_order) { \
StopInitOrderChecking(); \ StopInitOrderChecking(); \

View File

@ -167,6 +167,19 @@ extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN(uptr p, uptr size); SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN(uptr p, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN(uptr p, uptr size); SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN(uptr p, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16_noabort(uptr p);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN_noabort(uptr p, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN_noabort(uptr p, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load1(uptr p, u32 exp); SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load1(uptr p, u32 exp);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load2(uptr p, u32 exp); SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load2(uptr p, u32 exp);
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load4(uptr p, u32 exp); SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load4(uptr p, u32 exp);

View File

@ -75,8 +75,6 @@ void AsanCheckIncompatibleRT();
void AsanOnDeadlySignal(int, void *siginfo, void *context); void AsanOnDeadlySignal(int, void *siginfo, void *context);
void DisableReexec();
void MaybeReexec();
void ReadContextStack(void *context, uptr *stack, uptr *ssize); void ReadContextStack(void *context, uptr *stack, uptr *ssize);
void StopInitOrderChecking(); void StopInitOrderChecking();

View File

@ -70,14 +70,6 @@ namespace __asan {
void InitializePlatformInterceptors() {} void InitializePlatformInterceptors() {}
void DisableReexec() {
// No need to re-exec on Linux.
}
void MaybeReexec() {
// No need to re-exec on Linux.
}
void *AsanDoesNotSupportStaticLinkage() { void *AsanDoesNotSupportStaticLinkage() {
// This will fail to link with -static. // This will fail to link with -static.
return &_DYNAMIC; // defined in link.h return &_DYNAMIC; // defined in link.h

View File

@ -24,15 +24,6 @@
#include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_mac.h" #include "sanitizer_common/sanitizer_mac.h"
#if !SANITIZER_IOS
#include <crt_externs.h> // for _NSGetArgv and _NSGetEnviron
#else
extern "C" {
extern char ***_NSGetArgv(void);
}
#endif
#include <dlfcn.h> // for dladdr()
#include <fcntl.h> #include <fcntl.h>
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
@ -52,182 +43,12 @@ void InitializePlatformInterceptors() {}
bool PlatformHasDifferentMemcpyAndMemmove() { bool PlatformHasDifferentMemcpyAndMemmove() {
// On OS X 10.7 memcpy() and memmove() are both resolved // On OS X 10.7 memcpy() and memmove() are both resolved
// into memmove$VARIANT$sse42. // into memmove$VARIANT$sse42.
// See also http://code.google.com/p/address-sanitizer/issues/detail?id=34. // See also https://github.com/google/sanitizers/issues/34.
// TODO(glider): need to check dynamically that memcpy() and memmove() are // TODO(glider): need to check dynamically that memcpy() and memmove() are
// actually the same function. // actually the same function.
return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD; return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD;
} }
extern "C"
void __asan_init();
static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES";
LowLevelAllocator allocator_for_env;
// Change the value of the env var |name|, leaking the original value.
// If |name_value| is NULL, the variable is deleted from the environment,
// otherwise the corresponding "NAME=value" string is replaced with
// |name_value|.
void LeakyResetEnv(const char *name, const char *name_value) {
char **env = GetEnviron();
uptr name_len = internal_strlen(name);
while (*env != 0) {
uptr len = internal_strlen(*env);
if (len > name_len) {
const char *p = *env;
if (!internal_memcmp(p, name, name_len) && p[name_len] == '=') {
// Match.
if (name_value) {
// Replace the old value with the new one.
*env = const_cast<char*>(name_value);
} else {
// Shift the subsequent pointers back.
char **del = env;
do {
del[0] = del[1];
} while (*del++);
}
}
}
env++;
}
}
static bool reexec_disabled = false;
void DisableReexec() {
reexec_disabled = true;
}
extern "C" double dyldVersionNumber;
static const double kMinDyldVersionWithAutoInterposition = 360.0;
bool DyldNeedsEnvVariable() {
// If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if
// DYLD_INSERT_LIBRARIES is not set. However, checking OS version via
// GetMacosVersion() doesn't work for the simulator. Let's instead check
// `dyldVersionNumber`, which is exported by dyld, against a known version
// number from the first OS release where this appeared.
return dyldVersionNumber < kMinDyldVersionWithAutoInterposition;
}
void MaybeReexec() {
if (reexec_disabled) return;
// Make sure the dynamic ASan runtime library is preloaded so that the
// wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec
// ourselves.
Dl_info info;
CHECK(dladdr((void*)((uptr)__asan_init), &info));
char *dyld_insert_libraries =
const_cast<char*>(GetEnv(kDyldInsertLibraries));
uptr old_env_len = dyld_insert_libraries ?
internal_strlen(dyld_insert_libraries) : 0;
uptr fname_len = internal_strlen(info.dli_fname);
const char *dylib_name = StripModuleName(info.dli_fname);
uptr dylib_name_len = internal_strlen(dylib_name);
bool lib_is_in_env =
dyld_insert_libraries && REAL(strstr)(dyld_insert_libraries, dylib_name);
if (DyldNeedsEnvVariable() && !lib_is_in_env) {
// DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
// library.
char program_name[1024];
uint32_t buf_size = sizeof(program_name);
_NSGetExecutablePath(program_name, &buf_size);
char *new_env = const_cast<char*>(info.dli_fname);
if (dyld_insert_libraries) {
// Append the runtime dylib name to the existing value of
// DYLD_INSERT_LIBRARIES.
new_env = (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2);
internal_strncpy(new_env, dyld_insert_libraries, old_env_len);
new_env[old_env_len] = ':';
// Copy fname_len and add a trailing zero.
internal_strncpy(new_env + old_env_len + 1, info.dli_fname,
fname_len + 1);
// Ok to use setenv() since the wrappers don't depend on the value of
// asan_inited.
setenv(kDyldInsertLibraries, new_env, /*overwrite*/1);
} else {
// Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name.
setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
}
VReport(1, "exec()-ing the program with\n");
VReport(1, "%s=%s\n", kDyldInsertLibraries, new_env);
VReport(1, "to enable ASan wrappers.\n");
execv(program_name, *_NSGetArgv());
// We get here only if execv() failed.
Report("ERROR: The process is launched without DYLD_INSERT_LIBRARIES, "
"which is required for ASan to work. ASan tried to set the "
"environment variable and re-execute itself, but execv() failed, "
"possibly because of sandbox restrictions. Make sure to launch the "
"executable with:\n%s=%s\n", kDyldInsertLibraries, new_env);
CHECK("execv failed" && 0);
}
if (!lib_is_in_env)
return;
// DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove
// the dylib from the environment variable, because interceptors are installed
// and we don't want our children to inherit the variable.
uptr env_name_len = internal_strlen(kDyldInsertLibraries);
// Allocate memory to hold the previous env var name, its value, the '='
// sign and the '\0' char.
char *new_env = (char*)allocator_for_env.Allocate(
old_env_len + 2 + env_name_len);
CHECK(new_env);
internal_memset(new_env, '\0', old_env_len + 2 + env_name_len);
internal_strncpy(new_env, kDyldInsertLibraries, env_name_len);
new_env[env_name_len] = '=';
char *new_env_pos = new_env + env_name_len + 1;
// Iterate over colon-separated pieces of |dyld_insert_libraries|.
char *piece_start = dyld_insert_libraries;
char *piece_end = NULL;
char *old_env_end = dyld_insert_libraries + old_env_len;
do {
if (piece_start[0] == ':') piece_start++;
piece_end = REAL(strchr)(piece_start, ':');
if (!piece_end) piece_end = dyld_insert_libraries + old_env_len;
if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break;
uptr piece_len = piece_end - piece_start;
char *filename_start =
(char *)internal_memrchr(piece_start, '/', piece_len);
uptr filename_len = piece_len;
if (filename_start) {
filename_start += 1;
filename_len = piece_len - (filename_start - piece_start);
} else {
filename_start = piece_start;
}
// If the current piece isn't the runtime library name,
// append it to new_env.
if ((dylib_name_len != filename_len) ||
(internal_memcmp(filename_start, dylib_name, dylib_name_len) != 0)) {
if (new_env_pos != new_env + env_name_len + 1) {
new_env_pos[0] = ':';
new_env_pos++;
}
internal_strncpy(new_env_pos, piece_start, piece_len);
new_env_pos += piece_len;
}
// Move on to the next piece.
piece_start = piece_end;
} while (piece_start < old_env_end);
// Can't use setenv() here, because it requires the allocator to be
// initialized.
// FIXME: instead of filtering DYLD_INSERT_LIBRARIES here, do it in
// a separate function called after InitializeAllocator().
if (new_env_pos == new_env + env_name_len + 1) new_env = NULL;
LeakyResetEnv(kDyldInsertLibraries, new_env);
}
// No-op. Mac does not support static linkage anyway. // No-op. Mac does not support static linkage anyway.
void *AsanDoesNotSupportStaticLinkage() { void *AsanDoesNotSupportStaticLinkage() {
return 0; return 0;

View File

@ -26,13 +26,25 @@
// ---------------------- Replacement functions ---------------- {{{1 // ---------------------- Replacement functions ---------------- {{{1
using namespace __asan; // NOLINT using namespace __asan; // NOLINT
static const uptr kCallocPoolSize = 1024;
static uptr calloc_memory_for_dlsym[kCallocPoolSize];
static bool IsInCallocPool(const void *ptr) {
sptr off = (sptr)ptr - (sptr)calloc_memory_for_dlsym;
return 0 <= off && off < (sptr)kCallocPoolSize;
}
INTERCEPTOR(void, free, void *ptr) { INTERCEPTOR(void, free, void *ptr) {
GET_STACK_TRACE_FREE; GET_STACK_TRACE_FREE;
if (UNLIKELY(IsInCallocPool(ptr)))
return;
asan_free(ptr, &stack, FROM_MALLOC); asan_free(ptr, &stack, FROM_MALLOC);
} }
INTERCEPTOR(void, cfree, void *ptr) { INTERCEPTOR(void, cfree, void *ptr) {
GET_STACK_TRACE_FREE; GET_STACK_TRACE_FREE;
if (UNLIKELY(IsInCallocPool(ptr)))
return;
asan_free(ptr, &stack, FROM_MALLOC); asan_free(ptr, &stack, FROM_MALLOC);
} }
@ -44,8 +56,6 @@ INTERCEPTOR(void*, malloc, uptr size) {
INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
if (UNLIKELY(!asan_inited)) { if (UNLIKELY(!asan_inited)) {
// Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
const uptr kCallocPoolSize = 1024;
static uptr calloc_memory_for_dlsym[kCallocPoolSize];
static uptr allocated; static uptr allocated;
uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize; uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
void *mem = (void*)&calloc_memory_for_dlsym[allocated]; void *mem = (void*)&calloc_memory_for_dlsym[allocated];
@ -59,6 +69,13 @@ INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
INTERCEPTOR(void*, realloc, void *ptr, uptr size) { INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
GET_STACK_TRACE_MALLOC; GET_STACK_TRACE_MALLOC;
if (UNLIKELY(IsInCallocPool(ptr))) {
uptr offset = (uptr)ptr - (uptr)calloc_memory_for_dlsym;
uptr copy_size = Min(size, kCallocPoolSize - offset);
void *new_ptr = asan_malloc(size, &stack);
internal_memcpy(new_ptr, ptr, copy_size);
return new_ptr;
}
return asan_realloc(ptr, size, &stack); return asan_realloc(ptr, size, &stack);
} }

View File

@ -54,10 +54,6 @@ using namespace __asan;
#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \ #define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \
GET_STACK_TRACE_FREE; \ GET_STACK_TRACE_FREE; \
ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack); ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
#define COMMON_MALLOC_IGNORE_INVALID_FREE flags()->mac_ignore_invalid_free
#define COMMON_MALLOC_REPORT_FREE_UNALLOCATED(ptr, zone_ptr, zone_name) \
GET_STACK_TRACE_FREE; \
WarnMacFreeUnallocated((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
#define COMMON_MALLOC_NAMESPACE __asan #define COMMON_MALLOC_NAMESPACE __asan
#include "sanitizer_common/sanitizer_malloc_mac.inc" #include "sanitizer_common/sanitizer_malloc_mac.inc"

View File

@ -17,7 +17,7 @@
#include "asan_internal.h" #include "asan_internal.h"
// The full explanation of the memory mapping could be found here: // The full explanation of the memory mapping could be found here:
// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm // https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm
// //
// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000: // Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem || // || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
@ -118,11 +118,7 @@ static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000
static const u64 kIosShadowOffset64 = 0x130000000; static const u64 kIosShadowOffset64 = 0x130000000;
static const u64 kIosSimShadowOffset32 = 1ULL << 30; static const u64 kIosSimShadowOffset32 = 1ULL << 30;
static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64; static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64;
#if SANITIZER_AARCH64_VMA == 39
static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
#elif SANITIZER_AARCH64_VMA == 42
static const u64 kAArch64_ShadowOffset64 = 1ULL << 39;
#endif
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000; static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37; static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;

View File

@ -30,7 +30,7 @@
using namespace __asan; // NOLINT using namespace __asan; // NOLINT
// This code has issues on OSX. // This code has issues on OSX.
// See https://code.google.com/p/address-sanitizer/issues/detail?id=131. // See https://github.com/google/sanitizers/issues/131.
// Fake std::nothrow_t to avoid including <new>. // Fake std::nothrow_t to avoid including <new>.
namespace std { namespace std {

View File

@ -102,7 +102,7 @@ using namespace __asan; // NOLINT
// that user program (un)poisons the memory it owns. It poisons memory // that user program (un)poisons the memory it owns. It poisons memory
// conservatively, and unpoisons progressively to make sure asan shadow // conservatively, and unpoisons progressively to make sure asan shadow
// mapping invariant is preserved (see detailed mapping description here: // mapping invariant is preserved (see detailed mapping description here:
// http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm). // https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm).
// //
// * if user asks to poison region [left, right), the program poisons // * if user asks to poison region [left, right), the program poisons
// at least [left, AlignDown(right)). // at least [left, AlignDown(right)).
@ -354,7 +354,7 @@ void __sanitizer_annotate_contiguous_container(const void *beg_p,
// Make a quick sanity check that we are indeed in this state. // Make a quick sanity check that we are indeed in this state.
// //
// FIXME: Two of these three checks are disabled until we fix // FIXME: Two of these three checks are disabled until we fix
// https://code.google.com/p/address-sanitizer/issues/detail?id=258. // https://github.com/google/sanitizers/issues/258.
// if (d1 != d2) // if (d1 != d2)
// CHECK_EQ(*(u8*)MemToShadow(d1), old_mid - d1); // CHECK_EQ(*(u8*)MemToShadow(d1), old_mid - d1);
if (a + granularity <= d1) if (a + granularity <= d1)

View File

@ -77,6 +77,8 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
ReportStackOverflow(sig); ReportStackOverflow(sig);
else if (signo == SIGFPE) else if (signo == SIGFPE)
ReportDeadlySignal("FPE", sig); ReportDeadlySignal("FPE", sig);
else if (signo == SIGILL)
ReportDeadlySignal("ILL", sig);
else else
ReportDeadlySignal("SEGV", sig); ReportDeadlySignal("SEGV", sig);
} }

View File

@ -30,7 +30,9 @@ namespace __asan {
static void (*error_report_callback)(const char*); static void (*error_report_callback)(const char*);
static char *error_message_buffer = nullptr; static char *error_message_buffer = nullptr;
static uptr error_message_buffer_pos = 0; static uptr error_message_buffer_pos = 0;
static uptr error_message_buffer_size = 0; static BlockingMutex error_message_buf_mutex(LINKER_INITIALIZED);
static const unsigned kAsanBuggyPcPoolSize = 25;
static __sanitizer::atomic_uintptr_t AsanBuggyPcPool[kAsanBuggyPcPoolSize];
struct ReportData { struct ReportData {
uptr pc; uptr pc;
@ -46,16 +48,20 @@ static bool report_happened = false;
static ReportData report_data = {}; static ReportData report_data = {};
void AppendToErrorMessageBuffer(const char *buffer) { void AppendToErrorMessageBuffer(const char *buffer) {
if (error_message_buffer) { BlockingMutexLock l(&error_message_buf_mutex);
uptr length = internal_strlen(buffer); if (!error_message_buffer) {
CHECK_GE(error_message_buffer_size, error_message_buffer_pos); error_message_buffer =
uptr remaining = error_message_buffer_size - error_message_buffer_pos; (char*)MmapOrDieQuietly(kErrorMessageBufferSize, __func__);
internal_strncpy(error_message_buffer + error_message_buffer_pos, error_message_buffer_pos = 0;
buffer, remaining);
error_message_buffer[error_message_buffer_size - 1] = '\0';
// FIXME: reallocate the buffer instead of truncating the message.
error_message_buffer_pos += Min(remaining, length);
} }
uptr length = internal_strlen(buffer);
RAW_CHECK(kErrorMessageBufferSize >= error_message_buffer_pos);
uptr remaining = kErrorMessageBufferSize - error_message_buffer_pos;
internal_strncpy(error_message_buffer + error_message_buffer_pos,
buffer, remaining);
error_message_buffer[kErrorMessageBufferSize - 1] = '\0';
// FIXME: reallocate the buffer instead of truncating the message.
error_message_buffer_pos += Min(remaining, length);
} }
// ---------------------- Decorator ------------------------------ {{{1 // ---------------------- Decorator ------------------------------ {{{1
@ -622,26 +628,90 @@ void DescribeThread(AsanThreadContext *context) {
// immediately after printing error report. // immediately after printing error report.
class ScopedInErrorReport { class ScopedInErrorReport {
public: public:
explicit ScopedInErrorReport(ReportData *report = nullptr) { explicit ScopedInErrorReport(ReportData *report = nullptr,
static atomic_uint32_t num_calls; bool fatal = false) {
static u32 reporting_thread_tid; halt_on_error_ = fatal || flags()->halt_on_error;
if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
if (lock_.TryLock()) {
StartReporting(report);
return;
}
// ASan found two bugs in different threads simultaneously.
u32 current_tid = GetCurrentTidOrInvalid();
if (reporting_thread_tid_ == current_tid ||
reporting_thread_tid_ == kInvalidTid) {
// This is either asynch signal or nested error during error reporting.
// Fail simple to avoid deadlocks in Report().
// Can't use Report() here because of potential deadlocks
// in nested signal handlers.
const char msg[] = "AddressSanitizer: nested bug in the same thread, "
"aborting.\n";
WriteToFile(kStderrFd, msg, sizeof(msg));
internal__exit(common_flags()->exitcode);
}
if (halt_on_error_) {
// Do not print more than one report, otherwise they will mix up. // Do not print more than one report, otherwise they will mix up.
// Error reporting functions shouldn't return at this situation, as // Error reporting functions shouldn't return at this situation, as
// they are defined as no-return. // they are effectively no-returns.
Report("AddressSanitizer: while reporting a bug found another one. " Report("AddressSanitizer: while reporting a bug found another one. "
"Ignoring.\n"); "Ignoring.\n");
u32 current_tid = GetCurrentTidOrInvalid();
if (current_tid != reporting_thread_tid) { // Sleep long enough to make sure that the thread which started
// ASan found two bugs in different threads simultaneously. Sleep // to print an error report will finish doing it.
// long enough to make sure that the thread which started to print SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
// an error report will finish doing it.
SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
}
// If we're still not dead for some reason, use raw _exit() instead of // If we're still not dead for some reason, use raw _exit() instead of
// Die() to bypass any additional checks. // Die() to bypass any additional checks.
internal__exit(common_flags()->exitcode); internal__exit(common_flags()->exitcode);
} else {
// The other thread will eventually finish reporting
// so it's safe to wait
lock_.Lock();
} }
StartReporting(report);
}
~ScopedInErrorReport() {
// Make sure the current thread is announced.
DescribeThread(GetCurrentThread());
// We may want to grab this lock again when printing stats.
asanThreadRegistry().Unlock();
// Print memory stats.
if (flags()->print_stats)
__asan_print_accumulated_stats();
// Copy the message buffer so that we could start logging without holding a
// lock that gets aquired during printing.
InternalScopedBuffer<char> buffer_copy(kErrorMessageBufferSize);
{
BlockingMutexLock l(&error_message_buf_mutex);
internal_memcpy(buffer_copy.data(),
error_message_buffer, kErrorMessageBufferSize);
}
LogFullErrorReport(buffer_copy.data());
if (error_report_callback) {
error_report_callback(buffer_copy.data());
}
CommonSanitizerReportMutex.Unlock();
reporting_thread_tid_ = kInvalidTid;
lock_.Unlock();
if (halt_on_error_) {
Report("ABORTING\n");
Die();
}
}
private:
void StartReporting(ReportData *report) {
if (report) report_data = *report; if (report) report_data = *report;
report_happened = true; report_happened = true;
ASAN_ON_ERROR(); ASAN_ON_ERROR();
@ -651,27 +721,19 @@ class ScopedInErrorReport {
// recursive reports. // recursive reports.
asanThreadRegistry().Lock(); asanThreadRegistry().Lock();
CommonSanitizerReportMutex.Lock(); CommonSanitizerReportMutex.Lock();
reporting_thread_tid = GetCurrentTidOrInvalid(); reporting_thread_tid_ = GetCurrentTidOrInvalid();
Printf("====================================================" Printf("===================================================="
"=============\n"); "=============\n");
} }
// Destructor is NORETURN, as functions that report errors are.
NORETURN ~ScopedInErrorReport() { static StaticSpinMutex lock_;
// Make sure the current thread is announced. static u32 reporting_thread_tid_;
DescribeThread(GetCurrentThread()); bool halt_on_error_;
// We may want to grab this lock again when printing stats.
asanThreadRegistry().Unlock();
// Print memory stats.
if (flags()->print_stats)
__asan_print_accumulated_stats();
if (error_report_callback) {
error_report_callback(error_message_buffer);
}
Report("ABORTING\n");
Die();
}
}; };
StaticSpinMutex ScopedInErrorReport::lock_;
u32 ScopedInErrorReport::reporting_thread_tid_;
void ReportStackOverflow(const SignalContext &sig) { void ReportStackOverflow(const SignalContext &sig) {
ScopedInErrorReport in_report; ScopedInErrorReport in_report;
Decorator d; Decorator d;
@ -688,7 +750,7 @@ void ReportStackOverflow(const SignalContext &sig) {
} }
void ReportDeadlySignal(const char *description, const SignalContext &sig) { void ReportDeadlySignal(const char *description, const SignalContext &sig) {
ScopedInErrorReport in_report; ScopedInErrorReport in_report(/*report*/nullptr, /*fatal*/true);
Decorator d; Decorator d;
Printf("%s", d.Warning()); Printf("%s", d.Warning());
Report( Report(
@ -745,7 +807,7 @@ void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
stack.Print(); stack.Print();
DescribeHeapAddress(addr, 1); DescribeHeapAddress(addr, 1);
ReportErrorSummary("new-delete-type-mismatch", &stack); ReportErrorSummary("new-delete-type-mismatch", &stack);
Report("HINT: if you don't care about these warnings you may set " Report("HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=new_delete_type_mismatch=0\n"); "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
} }
@ -785,7 +847,7 @@ void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
stack.Print(); stack.Print();
DescribeHeapAddress(addr, 1); DescribeHeapAddress(addr, 1);
ReportErrorSummary("alloc-dealloc-mismatch", &stack); ReportErrorSummary("alloc-dealloc-mismatch", &stack);
Report("HINT: if you don't care about these warnings you may set " Report("HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=alloc_dealloc_mismatch=0\n"); "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
} }
@ -887,7 +949,7 @@ void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
Printf(" [2]:\n"); Printf(" [2]:\n");
StackDepotGet(stack_id2).Print(); StackDepotGet(stack_id2).Print();
} }
Report("HINT: if you don't care about these warnings you may set " Report("HINT: if you don't care about these errors you may set "
"ASAN_OPTIONS=detect_odr_violation=0\n"); "ASAN_OPTIONS=detect_odr_violation=0\n");
InternalScopedString error_msg(256); InternalScopedString error_msg(256);
error_msg.append("odr-violation: global '%s' at %s", error_msg.append("odr-violation: global '%s' at %s",
@ -926,17 +988,6 @@ static INLINE void CheckForInvalidPointerPair(void *p1, void *p2) {
} }
// ----------------------- Mac-specific reports ----------------- {{{1 // ----------------------- Mac-specific reports ----------------- {{{1
void WarnMacFreeUnallocated(uptr addr, uptr zone_ptr, const char *zone_name,
BufferedStackTrace *stack) {
// Just print a warning here.
Printf("free_common(%p) -- attempting to free unallocated memory.\n"
"AddressSanitizer is ignoring this error on Mac OS now.\n",
addr);
PrintZoneForPointer(addr, zone_ptr, zone_name);
stack->Print();
DescribeHeapAddress(addr, 1);
}
void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name, void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
BufferedStackTrace *stack) { BufferedStackTrace *stack) {
ScopedInErrorReport in_report; ScopedInErrorReport in_report;
@ -948,24 +999,23 @@ void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
DescribeHeapAddress(addr, 1); DescribeHeapAddress(addr, 1);
} }
void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name, // -------------- SuppressErrorReport -------------- {{{1
BufferedStackTrace *stack) { // Avoid error reports duplicating for ASan recover mode.
ScopedInErrorReport in_report; static bool SuppressErrorReport(uptr pc) {
Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n" if (!common_flags()->suppress_equal_pcs) return false;
"This is an unrecoverable problem, exiting now.\n", for (unsigned i = 0; i < kAsanBuggyPcPoolSize; i++) {
addr); uptr cmp = atomic_load_relaxed(&AsanBuggyPcPool[i]);
PrintZoneForPointer(addr, zone_ptr, zone_name); if (cmp == 0 && atomic_compare_exchange_strong(&AsanBuggyPcPool[i], &cmp,
stack->Print(); pc, memory_order_relaxed))
DescribeHeapAddress(addr, 1); return false;
if (cmp == pc) return true;
}
Die();
} }
} // namespace __asan void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
uptr access_size, u32 exp, bool fatal) {
// --------------------------- Interface --------------------- {{{1 if (!fatal && SuppressErrorReport(pc)) return;
using namespace __asan; // NOLINT
void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
uptr access_size, u32 exp) {
ENABLE_FRAME_POINTER; ENABLE_FRAME_POINTER;
// Optimization experiments. // Optimization experiments.
@ -1034,7 +1084,7 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
ReportData report = { pc, sp, bp, addr, (bool)is_write, access_size, ReportData report = { pc, sp, bp, addr, (bool)is_write, access_size,
bug_descr }; bug_descr };
ScopedInErrorReport in_report(&report); ScopedInErrorReport in_report(&report, fatal);
Decorator d; Decorator d;
Printf("%s", d.Warning()); Printf("%s", d.Warning());
@ -1060,14 +1110,21 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
PrintShadowMemoryForAddress(addr); PrintShadowMemoryForAddress(addr);
} }
} // namespace __asan
// --------------------------- Interface --------------------- {{{1
using namespace __asan; // NOLINT
void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
uptr access_size, u32 exp) {
ENABLE_FRAME_POINTER;
bool fatal = flags()->halt_on_error;
ReportGenericError(pc, bp, sp, addr, is_write, access_size, exp, fatal);
}
void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) { void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
BlockingMutexLock l(&error_message_buf_mutex);
error_report_callback = callback; error_report_callback = callback;
if (callback) {
error_message_buffer_size = 1 << 16;
error_message_buffer =
(char*)MmapOrDie(error_message_buffer_size, __func__);
error_message_buffer_pos = 0;
}
} }
void __asan_describe_address(uptr addr) { void __asan_describe_address(uptr addr) {

View File

@ -49,45 +49,39 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size);
void DescribeThread(AsanThreadContext *context); void DescribeThread(AsanThreadContext *context);
// Different kinds of error reports. // Different kinds of error reports.
void NORETURN ReportStackOverflow(const SignalContext &sig); void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
void NORETURN ReportDeadlySignal(const char* description, uptr access_size, u32 exp, bool fatal);
const SignalContext &sig); void ReportStackOverflow(const SignalContext &sig);
void NORETURN ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size, void ReportDeadlySignal(const char *description, const SignalContext &sig);
BufferedStackTrace *free_stack); void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
void NORETURN ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack); BufferedStackTrace *free_stack);
void NORETURN ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack); void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
void NORETURN ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack, void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);
AllocType alloc_type, void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
AllocType dealloc_type); AllocType alloc_type,
void NORETURN AllocType dealloc_type);
ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack); void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
void NORETURN void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
ReportSanitizerGetAllocatedSizeNotOwned(uptr addr, BufferedStackTrace *stack);
BufferedStackTrace *stack); void ReportStringFunctionMemoryRangesOverlap(const char *function,
void NORETURN const char *offset1, uptr length1,
ReportStringFunctionMemoryRangesOverlap(const char *function, const char *offset2, uptr length2,
const char *offset1, uptr length1, BufferedStackTrace *stack);
const char *offset2, uptr length2, void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
BufferedStackTrace *stack); BufferedStackTrace *stack);
void NORETURN ReportStringFunctionSizeOverflow(uptr offset, uptr size, void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
BufferedStackTrace *stack); uptr old_mid, uptr new_mid,
void NORETURN BufferedStackTrace *stack);
ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
uptr old_mid, uptr new_mid,
BufferedStackTrace *stack);
void NORETURN void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
ReportODRViolation(const __asan_global *g1, u32 stack_id1, const __asan_global *g2, u32 stack_id2);
const __asan_global *g2, u32 stack_id2);
// Mac-specific errors and warnings. // Mac-specific errors and warnings.
void WarnMacFreeUnallocated(uptr addr, uptr zone_ptr, const char *zone_name, void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,
BufferedStackTrace *stack); const char *zone_name,
void NORETURN ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, BufferedStackTrace *stack);
const char *zone_name, void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,
BufferedStackTrace *stack); const char *zone_name,
void NORETURN ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr, BufferedStackTrace *stack);
const char *zone_name,
BufferedStackTrace *stack);
} // namespace __asan } // namespace __asan

View File

@ -113,13 +113,18 @@ static void OnLowLevelAllocate(uptr ptr, uptr size) {
extern "C" NOINLINE INTERFACE_ATTRIBUTE \ extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_ ## type ## size(uptr addr) { \ void __asan_report_ ## type ## size(uptr addr) { \
GET_CALLER_PC_BP_SP; \ GET_CALLER_PC_BP_SP; \
__asan_report_error(pc, bp, sp, addr, is_write, size, 0); \ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
} \ } \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \ extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \ void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \
GET_CALLER_PC_BP_SP; \ GET_CALLER_PC_BP_SP; \
__asan_report_error(pc, bp, sp, addr, is_write, size, exp); \ ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
} } \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_ ## type ## size ## _noabort(uptr addr) { \
GET_CALLER_PC_BP_SP; \
ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
} \
ASAN_REPORT_ERROR(load, false, 1) ASAN_REPORT_ERROR(load, false, 1)
ASAN_REPORT_ERROR(load, false, 2) ASAN_REPORT_ERROR(load, false, 2)
@ -132,22 +137,27 @@ ASAN_REPORT_ERROR(store, true, 4)
ASAN_REPORT_ERROR(store, true, 8) ASAN_REPORT_ERROR(store, true, 8)
ASAN_REPORT_ERROR(store, true, 16) ASAN_REPORT_ERROR(store, true, 16)
#define ASAN_REPORT_ERROR_N(type, is_write) \ #define ASAN_REPORT_ERROR_N(type, is_write) \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \ extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_ ## type ## _n(uptr addr, uptr size) { \ void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
GET_CALLER_PC_BP_SP; \ GET_CALLER_PC_BP_SP; \
__asan_report_error(pc, bp, sp, addr, is_write, size, 0); \ ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
} \ } \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \ extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \ void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \
GET_CALLER_PC_BP_SP; \ GET_CALLER_PC_BP_SP; \
__asan_report_error(pc, bp, sp, addr, is_write, size, exp); \ ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
} } \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \
GET_CALLER_PC_BP_SP; \
ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
} \
ASAN_REPORT_ERROR_N(load, false) ASAN_REPORT_ERROR_N(load, false)
ASAN_REPORT_ERROR_N(store, true) ASAN_REPORT_ERROR_N(store, true)
#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg) \ #define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \
uptr sp = MEM_TO_SHADOW(addr); \ uptr sp = MEM_TO_SHADOW(addr); \
uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \ uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
: *reinterpret_cast<u16 *>(sp); \ : *reinterpret_cast<u16 *>(sp); \
@ -159,7 +169,8 @@ ASAN_REPORT_ERROR_N(store, true)
*__asan_test_only_reported_buggy_pointer = addr; \ *__asan_test_only_reported_buggy_pointer = addr; \
} else { \ } else { \
GET_CALLER_PC_BP_SP; \ GET_CALLER_PC_BP_SP; \
__asan_report_error(pc, bp, sp, addr, is_write, size, exp_arg); \ ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, \
fatal); \
} \ } \
} \ } \
} }
@ -167,12 +178,16 @@ ASAN_REPORT_ERROR_N(store, true)
#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \ #define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \ extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_##type##size(uptr addr) { \ void __asan_##type##size(uptr addr) { \
ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0) \ ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true) \
} \ } \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \ extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_exp_##type##size(uptr addr, u32 exp) { \ void __asan_exp_##type##size(uptr addr, u32 exp) { \
ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp) \ ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true) \
} } \
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
void __asan_##type##size ## _noabort(uptr addr) { \
ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false) \
} \
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1) ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2) ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
@ -190,7 +205,7 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_loadN(uptr addr, uptr size) { void __asan_loadN(uptr addr, uptr size) {
if (__asan_region_is_poisoned(addr, size)) { if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP; GET_CALLER_PC_BP_SP;
__asan_report_error(pc, bp, sp, addr, false, size, 0); ReportGenericError(pc, bp, sp, addr, false, size, 0, true);
} }
} }
@ -199,7 +214,16 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_exp_loadN(uptr addr, uptr size, u32 exp) { void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {
if (__asan_region_is_poisoned(addr, size)) { if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP; GET_CALLER_PC_BP_SP;
__asan_report_error(pc, bp, sp, addr, false, size, exp); ReportGenericError(pc, bp, sp, addr, false, size, exp, true);
}
}
extern "C"
NOINLINE INTERFACE_ATTRIBUTE
void __asan_loadN_noabort(uptr addr, uptr size) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
ReportGenericError(pc, bp, sp, addr, false, size, 0, false);
} }
} }
@ -208,7 +232,7 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_storeN(uptr addr, uptr size) { void __asan_storeN(uptr addr, uptr size) {
if (__asan_region_is_poisoned(addr, size)) { if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP; GET_CALLER_PC_BP_SP;
__asan_report_error(pc, bp, sp, addr, true, size, 0); ReportGenericError(pc, bp, sp, addr, true, size, 0, true);
} }
} }
@ -217,7 +241,16 @@ NOINLINE INTERFACE_ATTRIBUTE
void __asan_exp_storeN(uptr addr, uptr size, u32 exp) { void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {
if (__asan_region_is_poisoned(addr, size)) { if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP; GET_CALLER_PC_BP_SP;
__asan_report_error(pc, bp, sp, addr, true, size, exp); ReportGenericError(pc, bp, sp, addr, true, size, exp, true);
}
}
extern "C"
NOINLINE INTERFACE_ATTRIBUTE
void __asan_storeN_noabort(uptr addr, uptr size) {
if (__asan_region_is_poisoned(addr, size)) {
GET_CALLER_PC_BP_SP;
ReportGenericError(pc, bp, sp, addr, true, size, 0, false);
} }
} }
@ -293,6 +326,8 @@ static void InitializeHighMemEnd() {
} }
static void ProtectGap(uptr addr, uptr size) { static void ProtectGap(uptr addr, uptr size) {
if (!flags()->protect_shadow_gap)
return;
void *res = MmapNoAccess(addr, size, "shadow gap"); void *res = MmapNoAccess(addr, size, "shadow gap");
if (addr == (uptr)res) if (addr == (uptr)res)
return; return;
@ -378,8 +413,6 @@ static void AsanInitInternal() {
// initialization steps look at flags(). // initialization steps look at flags().
InitializeFlags(); InitializeFlags();
CheckVMASize();
AsanCheckIncompatibleRT(); AsanCheckIncompatibleRT();
AsanCheckDynamicRTPrereqs(); AsanCheckDynamicRTPrereqs();
@ -572,7 +605,7 @@ void NOINLINE __asan_handle_no_return() {
"stack top: %p; bottom %p; size: %p (%zd)\n" "stack top: %p; bottom %p; size: %p (%zd)\n"
"False positive error reports may follow\n" "False positive error reports may follow\n"
"For details see " "For details see "
"http://code.google.com/p/address-sanitizer/issues/detail?id=189\n", "https://github.com/google/sanitizers/issues/189\n",
top, bottom, top - bottom, top - bottom); top, bottom, top - bottom, top - bottom);
return; return;
} }

View File

@ -175,14 +175,6 @@ void PlatformTSDDtor(void *tsd) {
// }}} // }}}
// ---------------------- Various stuff ---------------- {{{ // ---------------------- Various stuff ---------------- {{{
void DisableReexec() {
// No need to re-exec on Windows.
}
void MaybeReexec() {
// No need to re-exec on Windows.
}
void *AsanDoesNotSupportStaticLinkage() { void *AsanDoesNotSupportStaticLinkage() {
#if defined(_DEBUG) #if defined(_DEBUG)
#error Please build the runtime with a non-debug CRT: /MD or /MT #error Please build the runtime with a non-debug CRT: /MD or /MT

View File

@ -12,8 +12,7 @@
// This file defines a family of thunks that should be statically linked into // This file defines a family of thunks that should be statically linked into
// the DLLs that have ASan instrumentation in order to delegate the calls to the // the DLLs that have ASan instrumentation in order to delegate the calls to the
// shared runtime that lives in the main binary. // shared runtime that lives in the main binary.
// See https://code.google.com/p/address-sanitizer/issues/detail?id=209 for the // See https://github.com/google/sanitizers/issues/209 for the details.
// details.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Only compile this code when buidling asan_dll_thunk.lib // Only compile this code when buidling asan_dll_thunk.lib
@ -257,6 +256,9 @@ INTERFACE_FUNCTION(__asan_memcpy);
INTERFACE_FUNCTION(__asan_memset); INTERFACE_FUNCTION(__asan_memset);
INTERFACE_FUNCTION(__asan_memmove); INTERFACE_FUNCTION(__asan_memmove);
INTERFACE_FUNCTION(__asan_alloca_poison);
INTERFACE_FUNCTION(__asan_allocas_unpoison);
INTERFACE_FUNCTION(__asan_register_globals) INTERFACE_FUNCTION(__asan_register_globals)
INTERFACE_FUNCTION(__asan_unregister_globals) INTERFACE_FUNCTION(__asan_unregister_globals)
@ -300,6 +302,7 @@ INTERFACE_FUNCTION(__asan_stack_free_10)
// FIXME: we might want to have a sanitizer_win_dll_thunk? // FIXME: we might want to have a sanitizer_win_dll_thunk?
INTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container) INTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container)
INTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address)
INTERFACE_FUNCTION(__sanitizer_cov) INTERFACE_FUNCTION(__sanitizer_cov)
INTERFACE_FUNCTION(__sanitizer_cov_dump) INTERFACE_FUNCTION(__sanitizer_cov_dump)
INTERFACE_FUNCTION(__sanitizer_cov_indir_call16) INTERFACE_FUNCTION(__sanitizer_cov_indir_call16)
@ -312,11 +315,13 @@ INTERFACE_FUNCTION(__sanitizer_cov_trace_switch)
INTERFACE_FUNCTION(__sanitizer_cov_with_check) INTERFACE_FUNCTION(__sanitizer_cov_with_check)
INTERFACE_FUNCTION(__sanitizer_get_allocated_size) INTERFACE_FUNCTION(__sanitizer_get_allocated_size)
INTERFACE_FUNCTION(__sanitizer_get_coverage_guards) INTERFACE_FUNCTION(__sanitizer_get_coverage_guards)
INTERFACE_FUNCTION(__sanitizer_get_coverage_pc_buffer)
INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes) INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes)
INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size) INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size)
INTERFACE_FUNCTION(__sanitizer_get_free_bytes) INTERFACE_FUNCTION(__sanitizer_get_free_bytes)
INTERFACE_FUNCTION(__sanitizer_get_heap_size) INTERFACE_FUNCTION(__sanitizer_get_heap_size)
INTERFACE_FUNCTION(__sanitizer_get_ownership) INTERFACE_FUNCTION(__sanitizer_get_ownership)
INTERFACE_FUNCTION(__sanitizer_get_total_unique_caller_callee_pairs)
INTERFACE_FUNCTION(__sanitizer_get_total_unique_coverage) INTERFACE_FUNCTION(__sanitizer_get_total_unique_coverage)
INTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes) INTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes)
INTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file) INTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file)

View File

@ -59,6 +59,7 @@ int __asan_option_detect_stack_use_after_return =
// using atexit() that calls a small subset of C terminators // using atexit() that calls a small subset of C terminators
// where LLVM global_dtors is placed. Fingers crossed, no other C terminators // where LLVM global_dtors is placed. Fingers crossed, no other C terminators
// are there. // are there.
extern "C" int __cdecl atexit(void (__cdecl *f)(void));
extern "C" void __cdecl _initterm(void *a, void *b); extern "C" void __cdecl _initterm(void *a, void *b);
namespace { namespace {

View File

@ -222,8 +222,13 @@ elif [[ -f "$HERE/$ASAN_RT" ]]; then
ASAN_RT_PATH="$HERE" ASAN_RT_PATH="$HERE"
elif [[ $(basename "$HERE") == "bin" ]]; then elif [[ $(basename "$HERE") == "bin" ]]; then
# We could be in the toolchain's base directory. # We could be in the toolchain's base directory.
# Consider ../lib, ../lib/asan, ../lib/linux and ../lib/clang/$VERSION/lib/linux. # Consider ../lib, ../lib/asan, ../lib/linux,
P=$(ls "$HERE"/../lib/"$ASAN_RT" "$HERE"/../lib/asan/"$ASAN_RT" "$HERE"/../lib/linux/"$ASAN_RT" "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1) # ../lib/clang/$VERSION/lib/linux, and ../lib64/clang/$VERSION/lib/linux.
P=$(ls "$HERE"/../lib/"$ASAN_RT" \
"$HERE"/../lib/asan/"$ASAN_RT" \
"$HERE"/../lib/linux/"$ASAN_RT" \
"$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" \
"$HERE"/../lib64/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1)
if [[ -n "$P" ]]; then if [[ -n "$P" ]]; then
ASAN_RT_PATH="$(dirname "$P")" ASAN_RT_PATH="$(dirname "$P")"
fi fi

View File

@ -271,7 +271,7 @@ def BreakpadSymbolizerFactory(binary):
def SystemSymbolizerFactory(system, addr, binary): def SystemSymbolizerFactory(system, addr, binary):
if system == 'Darwin': if system == 'Darwin':
return DarwinSymbolizer(addr, binary) return DarwinSymbolizer(addr, binary)
elif system == 'Linux': elif system == 'Linux' or system == 'FreeBSD':
return Addr2LineSymbolizer(binary) return Addr2LineSymbolizer(binary)

View File

@ -216,12 +216,12 @@ TEST(AddressSanitizerMac, NSObjectOOB) {
// Make sure that correct pointer is passed to free() when deallocating a // Make sure that correct pointer is passed to free() when deallocating a
// NSURL object. // NSURL object.
// See http://code.google.com/p/address-sanitizer/issues/detail?id=70. // See https://github.com/google/sanitizers/issues/70.
TEST(AddressSanitizerMac, NSURLDeallocation) { TEST(AddressSanitizerMac, NSURLDeallocation) {
TestNSURLDeallocation(); TestNSURLDeallocation();
} }
// See http://code.google.com/p/address-sanitizer/issues/detail?id=109. // See https://github.com/google/sanitizers/issues/109.
TEST(AddressSanitizerMac, Mstats) { TEST(AddressSanitizerMac, Mstats) {
malloc_statistics_t stats1, stats2; malloc_statistics_t stats1, stats2;
malloc_zone_statistics(/*all zones*/NULL, &stats1); malloc_zone_statistics(/*all zones*/NULL, &stats1);

View File

@ -34,7 +34,7 @@
// Make sure __asan_init is called before any test case is run. // Make sure __asan_init is called before any test case is run.
struct AsanInitCaller { struct AsanInitCaller {
AsanInitCaller() { AsanInitCaller() {
__asan::DisableReexec(); DisableReexec();
__asan_init(); __asan_init();
} }
}; };

View File

@ -610,7 +610,7 @@ NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {
} }
// Does not work on Power and ARM: // Does not work on Power and ARM:
// https://code.google.com/p/address-sanitizer/issues/detail?id=185 // https://github.com/google/sanitizers/issues/185
TEST(AddressSanitizer, BuiltinLongJmpTest) { TEST(AddressSanitizer, BuiltinLongJmpTest) {
static jmp_buf buf; static jmp_buf buf;
if (!__builtin_setjmp((void**)buf)) { if (!__builtin_setjmp((void**)buf)) {
@ -1156,9 +1156,9 @@ TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {
// The new/delete/etc mismatch checks don't work on Android, // The new/delete/etc mismatch checks don't work on Android,
// as calls to new/delete go through malloc/free. // as calls to new/delete go through malloc/free.
// OS X support is tracked here: // OS X support is tracked here:
// https://code.google.com/p/address-sanitizer/issues/detail?id=131 // https://github.com/google/sanitizers/issues/131
// Windows support is tracked here: // Windows support is tracked here:
// https://code.google.com/p/address-sanitizer/issues/detail?id=309 // https://github.com/google/sanitizers/issues/309
#if !defined(__ANDROID__) && \ #if !defined(__ANDROID__) && \
!defined(__APPLE__) && \ !defined(__APPLE__) && \
!defined(_WIN32) !defined(_WIN32)
@ -1255,7 +1255,7 @@ TEST(AddressSanitizer, DISABLED_DemoTooMuchMemoryTest) {
} }
} }
// http://code.google.com/p/address-sanitizer/issues/detail?id=66 // https://github.com/google/sanitizers/issues/66
TEST(AddressSanitizer, BufferOverflowAfterManyFrees) { TEST(AddressSanitizer, BufferOverflowAfterManyFrees) {
for (int i = 0; i < 1000000; i++) { for (int i = 0; i < 1000000; i++) {
delete [] (Ident(new char [8644])); delete [] (Ident(new char [8644]));

View File

@ -19,7 +19,8 @@ extern "C" const char* __asan_default_options() {
#if SANITIZER_MAC #if SANITIZER_MAC
// On Darwin, we default to `abort_on_error=1`, which would make tests run // On Darwin, we default to `abort_on_error=1`, which would make tests run
// much slower. Let's override this and run lit tests with 'abort_on_error=0'. // much slower. Let's override this and run lit tests with 'abort_on_error=0'.
return "symbolize=false:abort_on_error=0"; // Also, make sure we do not overwhelm the syslog while testing.
return "symbolize=false:abort_on_error=0:log_to_syslog=0";
#else #else
return "symbolize=false"; return "symbolize=false";
#endif #endif

View File

@ -2,6 +2,9 @@
# generic implementations of the core runtime library along with optimized # generic implementations of the core runtime library along with optimized
# architecture-specific code in various subdirectories. # architecture-specific code in various subdirectories.
# TODO: Need to add a mechanism for logging errors when builtin source files are
# added to a sub-directory and not this CMakeLists file.
set(GENERIC_SOURCES set(GENERIC_SOURCES
absvdi2.c absvdi2.c
absvsi2.c absvsi2.c
@ -150,7 +153,7 @@ if(APPLE)
atomic_thread_fence.c) atomic_thread_fence.c)
endif() endif()
if(NOT WIN32) if(NOT WIN32 OR MINGW)
set(GENERIC_SOURCES set(GENERIC_SOURCES
${GENERIC_SOURCES} ${GENERIC_SOURCES}
emutls.c) emutls.c)
@ -164,6 +167,8 @@ endif ()
if (NOT MSVC) if (NOT MSVC)
set(x86_64_SOURCES set(x86_64_SOURCES
x86_64/chkstk.S
x86_64/chkstk2.S
x86_64/floatdidf.c x86_64/floatdidf.c
x86_64/floatdisf.c x86_64/floatdisf.c
x86_64/floatdixf.c x86_64/floatdixf.c
@ -183,6 +188,8 @@ if (NOT MSVC)
set(i386_SOURCES set(i386_SOURCES
i386/ashldi3.S i386/ashldi3.S
i386/ashrdi3.S i386/ashrdi3.S
i386/chkstk.S
i386/chkstk2.S
i386/divdi3.S i386/divdi3.S
i386/floatdidf.S i386/floatdidf.S
i386/floatdisf.S i386/floatdisf.S
@ -219,7 +226,8 @@ else () # MSVC
set(i686_SOURCES ${i386_SOURCES}) set(i686_SOURCES ${i386_SOURCES})
endif () # if (NOT MSVC) endif () # if (NOT MSVC)
set(arm_SOURCES # These are sources that should be appropriate for any ARM platform.
set(arm_GENERIC_SOURCES
arm/aeabi_cdcmp.S arm/aeabi_cdcmp.S
arm/aeabi_cdcmpeq_check_nan.c arm/aeabi_cdcmpeq_check_nan.c
arm/aeabi_cfcmp.S arm/aeabi_cfcmp.S
@ -239,36 +247,16 @@ set(arm_SOURCES
arm/aeabi_uldivmod.S arm/aeabi_uldivmod.S
arm/bswapdi2.S arm/bswapdi2.S
arm/bswapsi2.S arm/bswapsi2.S
arm/clzdi2.S
arm/clzsi2.S
arm/comparesf2.S arm/comparesf2.S
arm/divmodsi4.S arm/divmodsi4.S
arm/divsi3.S arm/divsi3.S
arm/modsi3.S arm/modsi3.S
arm/negdf2vfp.S
arm/negsf2vfp.S
arm/switch16.S arm/switch16.S
arm/switch32.S arm/switch32.S
arm/switch8.S arm/switch8.S
arm/switchu8.S arm/switchu8.S
arm/sync_fetch_and_add_4.S
arm/sync_fetch_and_add_8.S
arm/sync_fetch_and_and_4.S
arm/sync_fetch_and_and_8.S
arm/sync_fetch_and_max_4.S
arm/sync_fetch_and_max_8.S
arm/sync_fetch_and_min_4.S
arm/sync_fetch_and_min_8.S
arm/sync_fetch_and_nand_4.S
arm/sync_fetch_and_nand_8.S
arm/sync_fetch_and_or_4.S
arm/sync_fetch_and_or_8.S
arm/sync_fetch_and_sub_4.S
arm/sync_fetch_and_sub_8.S
arm/sync_fetch_and_umax_4.S
arm/sync_fetch_and_umax_8.S
arm/sync_fetch_and_umin_4.S
arm/sync_fetch_and_umin_8.S
arm/sync_fetch_and_xor_4.S
arm/sync_fetch_and_xor_8.S
arm/sync_synchronize.S arm/sync_synchronize.S
arm/udivmodsi4.S arm/udivmodsi4.S
arm/udivsi3.S arm/udivsi3.S
@ -294,7 +282,32 @@ set(aarch64_SOURCES
trunctfsf2.c trunctfsf2.c
${GENERIC_SOURCES}) ${GENERIC_SOURCES})
set(armhf_SOURCES # These are sources for the ARM platform that require Thumb2 instructions
# support.
set(arm_THUMB_SOURCES
arm/sync_fetch_and_add_4.S
arm/sync_fetch_and_add_8.S
arm/sync_fetch_and_and_4.S
arm/sync_fetch_and_and_8.S
arm/sync_fetch_and_max_4.S
arm/sync_fetch_and_max_8.S
arm/sync_fetch_and_min_4.S
arm/sync_fetch_and_min_8.S
arm/sync_fetch_and_nand_4.S
arm/sync_fetch_and_nand_8.S
arm/sync_fetch_and_or_4.S
arm/sync_fetch_and_or_8.S
arm/sync_fetch_and_sub_4.S
arm/sync_fetch_and_sub_8.S
arm/sync_fetch_and_umax_4.S
arm/sync_fetch_and_umax_8.S
arm/sync_fetch_and_umin_4.S
arm/sync_fetch_and_umin_8.S
arm/sync_fetch_and_xor_4.S
arm/sync_fetch_and_xor_8.S)
# These are sources for the ARM platform that require VFP instructions support.
set(arm_VFP_SOURCES
arm/adddf3vfp.S arm/adddf3vfp.S
arm/addsf3vfp.S arm/addsf3vfp.S
arm/divdf3vfp.S arm/divdf3vfp.S
@ -320,6 +333,8 @@ set(armhf_SOURCES
arm/ltsf2vfp.S arm/ltsf2vfp.S
arm/muldf3vfp.S arm/muldf3vfp.S
arm/mulsf3vfp.S arm/mulsf3vfp.S
arm/negdf2vfp.S
arm/negsf2vfp.S
arm/nedf2vfp.S arm/nedf2vfp.S
arm/nesf2vfp.S arm/nesf2vfp.S
arm/restore_vfp_d8_d15_regs.S arm/restore_vfp_d8_d15_regs.S
@ -328,22 +343,31 @@ set(armhf_SOURCES
arm/subsf3vfp.S arm/subsf3vfp.S
arm/truncdfsf2vfp.S arm/truncdfsf2vfp.S
arm/unorddf2vfp.S arm/unorddf2vfp.S
arm/unordsf2vfp.S arm/unordsf2vfp.S)
${arm_SOURCES})
set(armv7_SOURCES ${arm_SOURCES}) set(arm_SOURCES ${arm_GENERIC_SOURCES})
set(armv7s_SOURCES ${arm_SOURCES}) set(armhf_SOURCES ${arm_GENERIC_SOURCES} ${arm_VFP_SOURCES})
set(armv7_SOURCES ${arm_GENERIC_SOURCES} ${arm_VFP_SOURCES} ${arm_THUMB_SOURCES})
set(armv7s_SOURCES ${arm_GENERIC_SOURCES} ${arm_VFP_SOURCES} ${arm_THUMB_SOURCES})
set(arm64_SOURCES ${aarch64_SOURCES}) set(arm64_SOURCES ${aarch64_SOURCES})
# macho_embedded archs # macho_embedded archs
set(armv6m_SOURCES ${GENERIC_SOURCES}) set(armv6m_SOURCES ${GENERIC_SOURCES})
set(armv7m_SOURCES ${arm_SOURCES}) set(armv7m_SOURCES ${arm_GENERIC_SOURCES} ${arm_THUMB_SOURCES})
set(armv7em_SOURCES ${arm_SOURCES}) set(armv7em_SOURCES ${arm_GENERIC_SOURCES} ${arm_THUMB_SOURCES})
set(mips_SOURCES ${GENERIC_SOURCES}) set(mips_SOURCES ${GENERIC_SOURCES})
set(mipsel_SOURCES ${mips_SOURCES}) set(mipsel_SOURCES ${mips_SOURCES})
set(mips64_SOURCES ${mips_SOURCES}) set(mips64_SOURCES ${mips_SOURCES})
set(mips64el_SOURCES ${mips_SOURCES}) set(mips64el_SOURCES ${mips_SOURCES})
set(powerpc_SOURCES ${GENERIC_SOURCES})
set(powerpc64_SOURCES ${GENERIC_SOURCES})
set(powerpc64le_SOURCES ${GENERIC_SOURCES})
set(wasm32_SOURCES ${GENERIC_SOURCES})
set(wasm64_SOURCES ${GENERIC_SOURCES})
add_custom_target(builtins) add_custom_target(builtins)
if (APPLE) if (APPLE)
@ -351,6 +375,8 @@ if (APPLE)
add_subdirectory(macho_embedded) add_subdirectory(macho_embedded)
darwin_add_builtin_libraries(${BUILTIN_SUPPORTED_OS}) darwin_add_builtin_libraries(${BUILTIN_SUPPORTED_OS})
else () else ()
append_string_if(COMPILER_RT_HAS_STD_C99_FLAG -std=c99 maybe_stdc99)
foreach (arch ${BUILTIN_SUPPORTED_ARCH}) foreach (arch ${BUILTIN_SUPPORTED_ARCH})
if (CAN_TARGET_${arch}) if (CAN_TARGET_${arch})
# Filter out generic versions of routines that are re-implemented in # Filter out generic versions of routines that are re-implemented in
@ -366,16 +392,14 @@ else ()
# Rust: don't insert a reference to MSVCRT.lib/etc # Rust: don't insert a reference to MSVCRT.lib/etc
if (MSVC) if (MSVC)
set(_cflags -Zl) set(maybe_zl -Zl)
else ()
set(_cflags -std=c99)
endif () endif ()
add_compiler_rt_runtime(clang_rt.builtins add_compiler_rt_runtime(clang_rt.builtins
STATIC STATIC
ARCHS ${arch} ARCHS ${arch}
SOURCES ${${arch}_SOURCES} SOURCES ${${arch}_SOURCES}
CFLAGS ${_cflags} CFLAGS ${maybe_stdc99} ${maybe_zl}
PARENT_TARGET builtins) PARENT_TARGET builtins)
endif () endif ()
endforeach () endforeach ()

View File

@ -1,3 +1,6 @@
absvti2
addtf3
addvti3
aeabi_cdcmp aeabi_cdcmp
aeabi_cdcmpeq_check_nan aeabi_cdcmpeq_check_nan
aeabi_cfcmp aeabi_cfcmp
@ -15,16 +18,13 @@ aeabi_memmove
aeabi_memset aeabi_memset
aeabi_uidivmod aeabi_uidivmod
aeabi_uldivmod aeabi_uldivmod
absvti2
addtf3
addvti3
ashlti3 ashlti3
ashrti3 ashrti3
clzti2 clzti2
cmpti2 cmpti2
ctzti2 ctzti2
divti3
divtf3 divtf3
divti3
ffsti2 ffsti2
fixdfti fixdfti
fixsfti fixsfti
@ -40,58 +40,16 @@ floatuntisf
floatuntixf floatuntixf
lshrti3 lshrti3
modti3 modti3
muloti4
multi3
multf3 multf3
multi3
mulvti3 mulvti3
negti2 negti2
negvti2 negvti2
parityti2 parityti2
popcountti2 popcountti2
powitf2 powitf2
subvti3
subtf3
trampoline_setup
ucmpti2
udivmodti4
udivti3
umodti3
absvti2
addtf3
addvti3
ashlti3
ashrti3
clzti2
cmpti2
ctzti2
divti3
divtf3
ffsti2
fixdfti
fixsfti
fixunsdfti
fixunssfti
fixunsxfti
fixxfti
floattidf
floattisf
floattixf
floatuntidf
floatuntisf
floatuntixf
lshrti3
modti3
muloti4
multi3
multf3
mulvti3
negti2
negvti2
parityti2
popcountti2
powitf2
subvti3
subtf3 subtf3
subvti3
trampoline_setup trampoline_setup
ucmpti2 ucmpti2
udivmodti4 udivmodti4

View File

@ -1,3 +1,6 @@
absvti2
addtf3
addvti3
aeabi_cdcmp aeabi_cdcmp
aeabi_cdcmpeq_check_nan aeabi_cdcmpeq_check_nan
aeabi_cfcmp aeabi_cfcmp
@ -15,16 +18,13 @@ aeabi_memmove
aeabi_memset aeabi_memset
aeabi_uidivmod aeabi_uidivmod
aeabi_uldivmod aeabi_uldivmod
absvti2
addtf3
addvti3
ashlti3 ashlti3
ashrti3 ashrti3
clzti2 clzti2
cmpti2 cmpti2
ctzti2 ctzti2
divti3
divtf3 divtf3
divti3
ffsti2 ffsti2
fixdfti fixdfti
fixsfti fixsfti
@ -40,58 +40,16 @@ floatuntisf
floatuntixf floatuntixf
lshrti3 lshrti3
modti3 modti3
muloti4 multf
multi3 multi3
multf3
mulvti3 mulvti3
negti2 negti2
negvti2 negvti2
parityti2 parityti2
popcountti2 popcountti2
powitf2 powitf2
subvti3
subtf3
trampoline_setup
ucmpti2
udivmodti4
udivti3
umodti3
absvti2
addtf3
addvti3
ashlti3
ashrti3
clzti2
cmpti2
ctzti2
divti3
divtf3
ffsti2
fixdfti
fixsfti
fixunsdfti
fixunssfti
fixunsxfti
fixxfti
floattidf
floattisf
floattixf
floatuntidf
floatuntisf
floatuntixf
lshrti3
modti3
muloti4
multi3
multf3
mulvti3
negti2
negvti2
parityti2
popcountti2
powitf2
subvti3
subtf3 subtf3
subvti3
trampoline_setup trampoline_setup
ucmpti2 ucmpti2
udivmodti4 udivmodti4

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__adddf3vfp)
vmov r0, r1, d6 // move result back to r0/r1 pair vmov r0, r1, d6 // move result back to r0/r1 pair
bx lr bx lr
END_COMPILERRT_FUNCTION(__adddf3vfp) END_COMPILERRT_FUNCTION(__adddf3vfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__addsf3vfp)
vmov r0, s14 // move result back to r0 vmov r0, s14 // move result back to r0
bx lr bx lr
END_COMPILERRT_FUNCTION(__addsf3vfp) END_COMPILERRT_FUNCTION(__addsf3vfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -94,3 +94,5 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
b __aeabi_cdcmple b __aeabi_cdcmple
END_COMPILERRT_FUNCTION(__aeabi_cdrcmple) END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
NO_EXEC_STACK_DIRECTIVE

View File

@ -89,3 +89,5 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
b __aeabi_cfcmple b __aeabi_cfcmple
END_COMPILERRT_FUNCTION(__aeabi_cfrcmple) END_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
NO_EXEC_STACK_DIRECTIVE

View File

@ -38,3 +38,6 @@ DEFINE_AEABI_DCMP(lt)
DEFINE_AEABI_DCMP(le) DEFINE_AEABI_DCMP(le)
DEFINE_AEABI_DCMP(ge) DEFINE_AEABI_DCMP(ge)
DEFINE_AEABI_DCMP(gt) DEFINE_AEABI_DCMP(gt)
NO_EXEC_STACK_DIRECTIVE

View File

@ -38,3 +38,6 @@ DEFINE_AEABI_FCMP(lt)
DEFINE_AEABI_FCMP(le) DEFINE_AEABI_FCMP(le)
DEFINE_AEABI_FCMP(ge) DEFINE_AEABI_FCMP(ge)
DEFINE_AEABI_FCMP(gt) DEFINE_AEABI_FCMP(gt)
NO_EXEC_STACK_DIRECTIVE

View File

@ -26,3 +26,6 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)
add sp, sp, #4 add sp, sp, #4
pop { pc } pop { pc }
END_COMPILERRT_FUNCTION(__aeabi_idivmod) END_COMPILERRT_FUNCTION(__aeabi_idivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@ -29,3 +29,6 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
add sp, sp, #16 add sp, sp, #16
pop {r11, pc} pop {r11, pc}
END_COMPILERRT_FUNCTION(__aeabi_ldivmod) END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@ -18,3 +18,6 @@ END_COMPILERRT_FUNCTION(__aeabi_memcmp)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -18,3 +18,6 @@ END_COMPILERRT_FUNCTION(__aeabi_memcpy)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy)
NO_EXEC_STACK_DIRECTIVE

View File

@ -18,3 +18,6 @@ END_COMPILERRT_FUNCTION(__aeabi_memmove)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove)
NO_EXEC_STACK_DIRECTIVE

View File

@ -32,3 +32,5 @@ END_COMPILERRT_FUNCTION(__aeabi_memclr)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
NO_EXEC_STACK_DIRECTIVE

View File

@ -27,3 +27,6 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod)
add sp, sp, #4 add sp, sp, #4
pop { pc } pop { pc }
END_COMPILERRT_FUNCTION(__aeabi_uidivmod) END_COMPILERRT_FUNCTION(__aeabi_uidivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@ -29,3 +29,6 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
add sp, sp, #16 add sp, sp, #16
pop {r11, pc} pop {r11, pc}
END_COMPILERRT_FUNCTION(__aeabi_uldivmod) END_COMPILERRT_FUNCTION(__aeabi_uldivmod)
NO_EXEC_STACK_DIRECTIVE

View File

@ -45,3 +45,6 @@ DEFINE_COMPILERRT_FUNCTION(__bswapdi2)
mov r1, r2 // r1 = r2 = rev(r0) mov r1, r2 // r1 = r2 = rev(r0)
JMP(lr) JMP(lr)
END_COMPILERRT_FUNCTION(__bswapdi2) END_COMPILERRT_FUNCTION(__bswapdi2)
NO_EXEC_STACK_DIRECTIVE

View File

@ -37,3 +37,6 @@ DEFINE_COMPILERRT_FUNCTION(__bswapsi2)
#endif #endif
JMP(lr) JMP(lr)
END_COMPILERRT_FUNCTION(__bswapsi2) END_COMPILERRT_FUNCTION(__bswapsi2)
NO_EXEC_STACK_DIRECTIVE

View File

@ -95,3 +95,6 @@ DEFINE_COMPILERRT_FUNCTION(__clzdi2)
JMP(lr) JMP(lr)
#endif // __ARM_FEATURE_CLZ #endif // __ARM_FEATURE_CLZ
END_COMPILERRT_FUNCTION(__clzdi2) END_COMPILERRT_FUNCTION(__clzdi2)
NO_EXEC_STACK_DIRECTIVE

View File

@ -74,3 +74,6 @@ DEFINE_COMPILERRT_FUNCTION(__clzsi2)
JMP(lr) JMP(lr)
#endif // __ARM_FEATURE_CLZ #endif // __ARM_FEATURE_CLZ
END_COMPILERRT_FUNCTION(__clzsi2) END_COMPILERRT_FUNCTION(__clzsi2)
NO_EXEC_STACK_DIRECTIVE

View File

@ -146,3 +146,6 @@ DEFINE_COMPILERRT_FUNCTION(__unordsf2)
END_COMPILERRT_FUNCTION(__unordsf2) END_COMPILERRT_FUNCTION(__unordsf2)
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_fcmpun, __unordsf2) DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_fcmpun, __unordsf2)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__divdf3vfp)
vmov r0, r1, d5 // move result back to r0/r1 pair vmov r0, r1, d5 // move result back to r0/r1 pair
bx lr bx lr
END_COMPILERRT_FUNCTION(__divdf3vfp) END_COMPILERRT_FUNCTION(__divdf3vfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -72,3 +72,6 @@ LOCAL_LABEL(divzero):
CLEAR_FRAME_AND_RETURN CLEAR_FRAME_AND_RETURN
#endif #endif
END_COMPILERRT_FUNCTION(__divmodsi4) END_COMPILERRT_FUNCTION(__divmodsi4)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__divsf3vfp)
vmov r0, s13 // move result back to r0 vmov r0, s13 // move result back to r0
bx lr bx lr
END_COMPILERRT_FUNCTION(__divsf3vfp) END_COMPILERRT_FUNCTION(__divsf3vfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -63,3 +63,6 @@ ESTABLISH_FRAME
CLEAR_FRAME_AND_RETURN CLEAR_FRAME_AND_RETURN
#endif #endif
END_COMPILERRT_FUNCTION(__divsi3) END_COMPILERRT_FUNCTION(__divsi3)
NO_EXEC_STACK_DIRECTIVE

View File

@ -27,3 +27,6 @@ DEFINE_COMPILERRT_FUNCTION(__eqdf2vfp)
movne r0, #0 movne r0, #0
bx lr bx lr
END_COMPILERRT_FUNCTION(__eqdf2vfp) END_COMPILERRT_FUNCTION(__eqdf2vfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -27,3 +27,6 @@ DEFINE_COMPILERRT_FUNCTION(__eqsf2vfp)
movne r0, #0 movne r0, #0
bx lr bx lr
END_COMPILERRT_FUNCTION(__eqsf2vfp) END_COMPILERRT_FUNCTION(__eqsf2vfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__extendsfdf2vfp)
vmov r0, r1, d7 // return result in r0/r1 pair vmov r0, r1, d7 // return result in r0/r1 pair
bx lr bx lr
END_COMPILERRT_FUNCTION(__extendsfdf2vfp) END_COMPILERRT_FUNCTION(__extendsfdf2vfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__fixdfsivfp)
vmov r0, s15 // move s15 to result register vmov r0, s15 // move s15 to result register
bx lr bx lr
END_COMPILERRT_FUNCTION(__fixdfsivfp) END_COMPILERRT_FUNCTION(__fixdfsivfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__fixsfsivfp)
vmov r0, s15 // move s15 to result register vmov r0, s15 // move s15 to result register
bx lr bx lr
END_COMPILERRT_FUNCTION(__fixsfsivfp) END_COMPILERRT_FUNCTION(__fixsfsivfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -25,3 +25,6 @@ DEFINE_COMPILERRT_FUNCTION(__fixunsdfsivfp)
vmov r0, s15 // move s15 to result register vmov r0, s15 // move s15 to result register
bx lr bx lr
END_COMPILERRT_FUNCTION(__fixunsdfsivfp) END_COMPILERRT_FUNCTION(__fixunsdfsivfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -25,3 +25,6 @@ DEFINE_COMPILERRT_FUNCTION(__fixunssfsivfp)
vmov r0, s15 // move s15 to result register vmov r0, s15 // move s15 to result register
bx lr bx lr
END_COMPILERRT_FUNCTION(__fixunssfsivfp) END_COMPILERRT_FUNCTION(__fixunssfsivfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__floatsidfvfp)
vmov r0, r1, d7 // move d7 to result register pair r0/r1 vmov r0, r1, d7 // move d7 to result register pair r0/r1
bx lr bx lr
END_COMPILERRT_FUNCTION(__floatsidfvfp) END_COMPILERRT_FUNCTION(__floatsidfvfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__floatsisfvfp)
vmov r0, s15 // move s15 to result register vmov r0, s15 // move s15 to result register
bx lr bx lr
END_COMPILERRT_FUNCTION(__floatsisfvfp) END_COMPILERRT_FUNCTION(__floatsisfvfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__floatunssidfvfp)
vmov r0, r1, d7 // move d7 to result register pair r0/r1 vmov r0, r1, d7 // move d7 to result register pair r0/r1
bx lr bx lr
END_COMPILERRT_FUNCTION(__floatunssidfvfp) END_COMPILERRT_FUNCTION(__floatunssidfvfp)
NO_EXEC_STACK_DIRECTIVE

View File

@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__floatunssisfvfp)
vmov r0, s15 // move s15 to result register vmov r0, s15 // move s15 to result register
bx lr bx lr
END_COMPILERRT_FUNCTION(__floatunssisfvfp) END_COMPILERRT_FUNCTION(__floatunssisfvfp)
NO_EXEC_STACK_DIRECTIVE

Some files were not shown because too many files have changed in this diff Show More