mirror of
https://git.proxmox.com/git/rustc
synced 2025-05-02 17:25:45 +00:00
Imported Upstream version 1.11.0+dfsg1
This commit is contained in:
parent
a7813a04b4
commit
3157f602e5
@ -108,7 +108,8 @@ root.
|
||||
There are large number of options accepted by this script to alter the
|
||||
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`
|
||||
to make a debug build with optimizations)
|
||||
- `--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:
|
||||
|
||||
- `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
|
||||
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
|
||||
(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
|
||||
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
|
||||
|
21
Makefile.in
21
Makefile.in
@ -62,6 +62,8 @@
|
||||
# * tidy - Basic style check, show highest rustc error code and
|
||||
# the status of language and lib features
|
||||
# * 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
|
||||
# ultimate power of The Rust Build System.
|
||||
@ -93,6 +95,15 @@
|
||||
# // Modifying libstd? Use this command to run unit tests just on your change
|
||||
# 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
|
||||
# make check-stage1-rpass TESTNAME=my-shiny-new-test
|
||||
#
|
||||
@ -266,13 +277,17 @@ endif
|
||||
|
||||
# CTAGS building
|
||||
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)
|
||||
include $(CFG_SRC_DIR)mk/ctags.mk
|
||||
endif
|
||||
|
||||
.DEFAULT:
|
||||
@echo "\n======================================================"
|
||||
@echo
|
||||
@echo "======================================================"
|
||||
@echo "== If you need help, run 'make help' or 'make tips' =="
|
||||
@echo "======================================================\n"
|
||||
@echo "======================================================"
|
||||
@echo
|
||||
exit 1
|
||||
|
71
README.md
71
README.md
@ -1,7 +1,7 @@
|
||||
# The Rust Programming Language
|
||||
|
||||
This is the main source code repository for [Rust]. It contains the compiler, standard library,
|
||||
and documentation.
|
||||
This is the main source code repository for [Rust]. It contains the compiler,
|
||||
standard library, and documentation.
|
||||
|
||||
[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
|
||||
* `python` 2.7 (but not 3.x)
|
||||
* GNU `make` 3.81 or later
|
||||
* `cmake` 2.8.8 or later
|
||||
* `curl`
|
||||
* `git`
|
||||
|
||||
@ -63,35 +64,37 @@ build.
|
||||
|
||||
#### 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
|
||||
tools.
|
||||
1. Grab the latest [MSYS2 installer][msys2] and go through the installer.
|
||||
|
||||
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
|
||||
# Update package mirrors (may be needed if you have a fresh install of MSYS2)
|
||||
$ 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
|
||||
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:
|
||||
4. Navigate to Rust's source code (or clone it), then configure and build it:
|
||||
|
||||
```sh
|
||||
$ ./configure
|
||||
@ -111,12 +114,25 @@ $ ./configure
|
||||
$ 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
|
||||
|
||||
If you’d like to build the documentation, it’s almost the same:
|
||||
|
||||
```sh
|
||||
./configure
|
||||
$ ./configure
|
||||
$ 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
|
||||
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
|
||||
swap, it will take a very long time to build.
|
||||
Rust currently needs between 600MiB and 1.5GiB to build, depending on platform.
|
||||
If it hits swap, it will take a very long time to build.
|
||||
|
||||
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
|
||||
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
398
configure
vendored
@ -133,12 +133,13 @@ probe() {
|
||||
}
|
||||
|
||||
probe_need() {
|
||||
local V=$1
|
||||
probe $*
|
||||
local V=$1
|
||||
shift
|
||||
eval VV=\$$V
|
||||
if [ -z "$VV" ]
|
||||
then
|
||||
err "needed, but unable to find any of: $*"
|
||||
err "$V needed, but unable to find any of: $*"
|
||||
fi
|
||||
}
|
||||
|
||||
@ -593,12 +594,13 @@ opt docs 1 "build standard library documentation"
|
||||
opt compiler-docs 0 "build compiler documentation"
|
||||
opt optimize-tests 1 "build tests with optimizations"
|
||||
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 debug-assertions 0 "build with debugging assertions"
|
||||
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 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 rpath 1 "build rpaths into rustc itself"
|
||||
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"
|
||||
|
||||
probe_need CFG_CURLORWGET curl wget
|
||||
probe_need CFG_CURL curl
|
||||
if [ -z "$CFG_PYTHON_PROVIDED" ]; then
|
||||
probe_need CFG_PYTHON python2.7 python2 python
|
||||
fi
|
||||
@ -773,6 +775,9 @@ probe CFG_BISON bison
|
||||
probe CFG_GDB gdb
|
||||
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
|
||||
# installed. Since `javac` is only used if `antlr4` is available,
|
||||
# probe for it only in this case.
|
||||
@ -847,6 +852,16 @@ then
|
||||
BIN_SUF=.exe
|
||||
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" ]
|
||||
then
|
||||
system_rustc=$(which rustc)
|
||||
@ -976,11 +991,11 @@ then
|
||||
LLVM_VERSION=$($LLVM_CONFIG --version)
|
||||
|
||||
case $LLVM_VERSION in
|
||||
(3.[6-8]*)
|
||||
(3.[7-8]*)
|
||||
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
|
||||
fi
|
||||
@ -1163,36 +1178,6 @@ do
|
||||
;;
|
||||
|
||||
*-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
|
||||
# The Cygwin build does not have generators for Visual Studio, so
|
||||
# detect that here and error.
|
||||
@ -1276,6 +1261,36 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
|
||||
esac
|
||||
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" ]
|
||||
then
|
||||
HAVE_PERF_LOGFD=`$CFG_PERF stat --log-fd 2>&1 | grep 'unknown option'`
|
||||
@ -1465,27 +1480,16 @@ do
|
||||
elif [ -z $CFG_LLVM_ROOT ]
|
||||
then
|
||||
LLVM_BUILD_DIR=${CFG_BUILD_DIR}$t/llvm
|
||||
if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ]
|
||||
then
|
||||
LLVM_DBG_OPTS="--enable-debug-symbols --disable-optimized"
|
||||
# Just use LLVM straight from its build directory to
|
||||
# avoid 'make install' time
|
||||
LLVM_INST_DIR=$LLVM_BUILD_DIR/Debug
|
||||
else
|
||||
LLVM_DBG_OPTS="--enable-optimized"
|
||||
LLVM_INST_DIR=$LLVM_BUILD_DIR/Release
|
||||
fi
|
||||
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
|
||||
LLVM_INST_DIR=$LLVM_BUILD_DIR
|
||||
# For some crazy reason the MSVC output dir is different than Unix
|
||||
if [ ${is_msvc} -ne 0 ]; then
|
||||
if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ]
|
||||
then
|
||||
# Just use LLVM straight from its build directory to
|
||||
# avoid 'make install' time
|
||||
LLVM_INST_DIR=$LLVM_BUILD_DIR/Debug
|
||||
else
|
||||
LLVM_INST_DIR=$LLVM_BUILD_DIR/Release
|
||||
fi
|
||||
fi
|
||||
else
|
||||
@ -1543,88 +1547,60 @@ do
|
||||
err "can only build LLVM for x86 platforms"
|
||||
;;
|
||||
esac
|
||||
CFG_CMAKE_GENERATOR=$generator
|
||||
putvar CFG_CMAKE_GENERATOR
|
||||
else
|
||||
generator="Unix Makefiles"
|
||||
fi
|
||||
CFG_CMAKE_GENERATOR=$generator
|
||||
putvar CFG_CMAKE_GENERATOR
|
||||
|
||||
if [ ${do_reconfigure} -ne 0 ] && [ ${is_msvc} -ne 0 ]
|
||||
then
|
||||
msg "configuring LLVM for $t with cmake"
|
||||
msg "configuring LLVM for $t"
|
||||
|
||||
CMAKE_ARGS="-DLLVM_INCLUDE_TESTS=OFF"
|
||||
if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ]; then
|
||||
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
|
||||
LLVM_CFLAGS_32=""
|
||||
LLVM_CXXFLAGS_32=""
|
||||
LLVM_LDFLAGS_32=""
|
||||
LLVM_CFLAGS_64=""
|
||||
LLVM_CXXFLAGS_64=""
|
||||
LLVM_LDFLAGS_64=""
|
||||
|
||||
msg "configuring LLVM with:"
|
||||
msg "$CMAKE_ARGS"
|
||||
case "$CFG_CC" in
|
||||
("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 \
|
||||
-G "$CFG_CMAKE_GENERATOR" \
|
||||
$CMAKE_ARGS)
|
||||
need_ok "LLVM cmake configure failed"
|
||||
fi
|
||||
|
||||
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"
|
||||
LLVM_CXX_64="ccache"
|
||||
LLVM_CC_64="ccache"
|
||||
LLVM_CXX_64_ARG1="clang++"
|
||||
LLVM_CC_64_ARG1="clang"
|
||||
LLVM_CFLAGS_64="-Qunused-arguments"
|
||||
LLVM_CXXFLAGS_64="-Qunused-arguments"
|
||||
;;
|
||||
esac
|
||||
("clang")
|
||||
LLVM_CXX_32="clang++"
|
||||
LLVM_CC_32="clang"
|
||||
LLVM_CFLAGS_32="-Qunused-arguments"
|
||||
LLVM_CXXFLAGS_32="-Qunused-arguments"
|
||||
|
||||
case "$CFG_CC" in
|
||||
("ccache clang")
|
||||
LLVM_CXX_32="ccache clang++ -Qunused-arguments"
|
||||
LLVM_CC_32="ccache clang -Qunused-arguments"
|
||||
|
||||
LLVM_CXX_64="ccache clang++ -Qunused-arguments"
|
||||
LLVM_CC_64="ccache clang -Qunused-arguments"
|
||||
LLVM_CXX_64="clang++"
|
||||
LLVM_CC_64="clang"
|
||||
LLVM_CFLAGS_64="-Qunused-arguments"
|
||||
LLVM_CXXFLAGS_64="-Qunused-arguments"
|
||||
;;
|
||||
("clang")
|
||||
LLVM_CXX_32="clang++ -Qunused-arguments"
|
||||
LLVM_CC_32="clang -Qunused-arguments"
|
||||
("ccache gcc")
|
||||
LLVM_CXX_32="ccache"
|
||||
LLVM_CC_32="ccache"
|
||||
LLVM_CXX_32_ARG1="clang++"
|
||||
LLVM_CC_32_ARG1="clang"
|
||||
|
||||
LLVM_CXX_64="clang++ -Qunused-arguments"
|
||||
LLVM_CC_64="clang -Qunused-arguments"
|
||||
LLVM_CXX_64="ccache"
|
||||
LLVM_CC_64="ccache"
|
||||
LLVM_CXX_64_ARG1="g++"
|
||||
LLVM_CC_64_ARG1="gcc"
|
||||
;;
|
||||
("ccache gcc")
|
||||
LLVM_CXX_32="ccache g++"
|
||||
LLVM_CC_32="ccache gcc"
|
||||
|
||||
LLVM_CXX_64="ccache g++"
|
||||
LLVM_CC_64="ccache gcc"
|
||||
;;
|
||||
("gcc")
|
||||
("gcc")
|
||||
LLVM_CXX_32="g++"
|
||||
LLVM_CC_32="gcc"
|
||||
|
||||
@ -1632,7 +1608,7 @@ do
|
||||
LLVM_CC_64="gcc"
|
||||
;;
|
||||
|
||||
(*)
|
||||
(*)
|
||||
msg "inferring LLVM_CXX/CC from CXX/CC = $CXX/$CC"
|
||||
if [ -n "$CFG_ENABLE_CCACHE" ]
|
||||
then
|
||||
@ -1641,11 +1617,15 @@ do
|
||||
err "ccache requested but not found"
|
||||
fi
|
||||
|
||||
LLVM_CXX_32="ccache $CXX"
|
||||
LLVM_CC_32="ccache $CC"
|
||||
LLVM_CXX_32="ccache"
|
||||
LLVM_CC_32="ccache"
|
||||
LLVM_CXX_32_ARG1="$CXX"
|
||||
LLVM_CC_32_ARG1="$CC"
|
||||
|
||||
LLVM_CXX_64="ccache $CXX"
|
||||
LLVM_CC_64="ccache $CC"
|
||||
LLVM_CXX_64="ccache"
|
||||
LLVM_CC_64="ccache"
|
||||
LLVM_CXX_64_ARG1="$CXX"
|
||||
LLVM_CC_64_ARG1="$CC"
|
||||
else
|
||||
LLVM_CXX_32="$CXX"
|
||||
LLVM_CC_32="$CC"
|
||||
@ -1655,86 +1635,102 @@ do
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
|
||||
case "$CFG_CPUTYPE" in
|
||||
(x86*)
|
||||
LLVM_CXX_32="$LLVM_CXX_32 -m32"
|
||||
LLVM_CC_32="$LLVM_CC_32 -m32"
|
||||
case "$CFG_CPUTYPE" in
|
||||
(x86*)
|
||||
LLVM_CFLAGS_32="$LLVM_CFLAGS_32 -m32"
|
||||
LLVM_CXXFLAGS_32="$LLVM_CXXFLAGS_32 -m32"
|
||||
LLVM_LDFLAGS_32="$LLVM_LDFLAGS_32 -m32"
|
||||
;;
|
||||
esac
|
||||
|
||||
LLVM_CFLAGS_32="-m32"
|
||||
LLVM_CXXFLAGS_32="-m32"
|
||||
LLVM_LDFLAGS_32="-m32"
|
||||
if echo $t | grep -q x86_64
|
||||
then
|
||||
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=""
|
||||
LLVM_CXXFLAGS_64=""
|
||||
LLVM_LDFLAGS_64=""
|
||||
if [ "$CFG_USING_LIBCPP" != "0" ]; then
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_LIBCXX=ON"
|
||||
fi
|
||||
|
||||
LLVM_CXX_32="$LLVM_CXX_32 -m32"
|
||||
LLVM_CC_32="$LLVM_CC_32 -m32"
|
||||
;;
|
||||
# Turn off things we don't need
|
||||
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"
|
||||
|
||||
(*)
|
||||
LLVM_CFLAGS_32=""
|
||||
LLVM_CXXFLAGS_32=""
|
||||
LLVM_LDFLAGS_32=""
|
||||
arch="$(echo "$t" | cut -d - -f 1)"
|
||||
|
||||
LLVM_CFLAGS_64=""
|
||||
LLVM_CXXFLAGS_64=""
|
||||
LLVM_LDFLAGS_64=""
|
||||
;;
|
||||
esac
|
||||
if [ "$arch" = i686 ]; then
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_BUILD_32_BITS=ON"
|
||||
fi
|
||||
|
||||
if echo $t | grep -q x86_64
|
||||
then
|
||||
LLVM_CXX=$LLVM_CXX_64
|
||||
LLVM_CC=$LLVM_CC_64
|
||||
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_CFLAGS=$LLVM_CFLAGS_32
|
||||
LLVM_CXXFLAGS=$LLVM_CXXFLAGS_32
|
||||
LLVM_LDFLAGS=$LLVM_LDFLAGS_32
|
||||
if [ "$t" != "$CFG_BUILD" ]; then
|
||||
# see http://llvm.org/docs/HowToCrossCompileLLVM.html
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CROSSCOMPILING=True"
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TARGET_ARCH=$arch"
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_TABLEGEN=$CFG_BUILD_DIR/$CFG_BUILD/llvm/bin/llvm-tblgen"
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_DEFAULT_TARGET_TRIPLE=$t"
|
||||
fi
|
||||
|
||||
# MSVC handles compiler business itself
|
||||
if [ ${is_msvc} -eq 0 ]; then
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_C_COMPILER=$LLVM_CC"
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CXX_COMPILER=$LLVM_CXX"
|
||||
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
|
||||
|
||||
CXX=$LLVM_CXX
|
||||
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"
|
||||
if [ -n "$LLVM_CXX_ARG1" ]; then
|
||||
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_CXX_COMPILER_ARG1=$LLVM_CXX_ARG1"
|
||||
fi
|
||||
# FIXME: What about LDFLAGS?
|
||||
fi
|
||||
|
||||
LLVM_FLAGS="$LLVM_TARGETS $LLVM_OPTS $LLVM_BUILD \
|
||||
$LLVM_HOST $LLVM_TARGET --with-python=$CFG_PYTHON"
|
||||
if [ -n "$CFG_DISABLE_OPTIMIZE_LLVM" ]; then
|
||||
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 "$LLVM_FLAGS"
|
||||
msg "$CMAKE_ARGS"
|
||||
|
||||
export CXX
|
||||
export CC
|
||||
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
|
||||
(cd $LLVM_BUILD_DIR && eval "\"$CFG_CMAKE\"" $CMAKE_ARGS)
|
||||
need_ok "LLVM cmake configure failed"
|
||||
fi
|
||||
|
||||
# Construct variables for LLVM build and install directories for
|
||||
|
@ -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_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
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_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=
|
||||
|
@ -1,6 +1,6 @@
|
||||
# i686-unknown-linux-musl configuration
|
||||
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
|
||||
AR_i686-unknown-linux-musl=$(AR)
|
||||
CFG_INSTALL_ONLY_RLIB_i686-unknown-linux-musl = 1
|
||||
|
@ -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_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
|
||||
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_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -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 -mabi=32 $(CFLAGS)
|
||||
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_LLC_FLAGS_mips-unknown-linux-gnu :=
|
||||
CFG_INSTALL_NAME_mips-unknown-linux-gnu =
|
||||
|
@ -1,6 +1,6 @@
|
||||
# x86_64-unknown-linux-musl configuration
|
||||
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
|
||||
AR_x86_64-unknown-linux-musl=$(AR)
|
||||
CFG_INSTALL_ONLY_RLIB_x86_64-unknown-linux-musl = 1
|
||||
|
46
mk/crates.mk
46
mk/crates.mk
@ -57,10 +57,10 @@ TARGET_CRATES := libc std term \
|
||||
panic_abort panic_unwind unwind
|
||||
RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_driver \
|
||||
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_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
|
||||
TOOLS := compiletest rustdoc rustc rustbook error_index_generator
|
||||
|
||||
@ -98,43 +98,45 @@ DEPS_serialize := std log
|
||||
DEPS_term := std
|
||||
DEPS_test := std getopts term native:rust_test_helpers
|
||||
|
||||
DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode
|
||||
DEPS_syntax_ext := syntax fmt_macros
|
||||
DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos
|
||||
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_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 \
|
||||
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_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_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
|
||||
rustc_typeck rustc_mir rustc_resolve log syntax serialize rustc_llvm \
|
||||
rustc_trans rustc_privacy rustc_lint rustc_plugin \
|
||||
rustc_metadata syntax_ext rustc_passes rustc_save_analysis rustc_const_eval \
|
||||
rustc_incremental
|
||||
DEPS_rustc_lint := rustc log syntax rustc_const_eval
|
||||
rustc_incremental syntax_pos rustc_errors
|
||||
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_metadata := rustc syntax rbml rustc_const_math
|
||||
DEPS_rustc_passes := syntax rustc core rustc_const_eval
|
||||
DEPS_rustc_mir := rustc syntax rustc_const_math rustc_const_eval rustc_bitflags
|
||||
DEPS_rustc_resolve := arena rustc log syntax
|
||||
DEPS_rustc_metadata := rustc syntax syntax_pos rustc_errors rbml rustc_const_math
|
||||
DEPS_rustc_passes := syntax syntax_pos rustc core rustc_const_eval rustc_errors
|
||||
DEPS_rustc_mir := rustc syntax syntax_pos rustc_const_math rustc_const_eval rustc_bitflags
|
||||
DEPS_rustc_resolve := arena rustc log syntax syntax_pos rustc_errors
|
||||
DEPS_rustc_platform_intrinsics := std
|
||||
DEPS_rustc_plugin := rustc rustc_metadata syntax rustc_mir
|
||||
DEPS_rustc_privacy := rustc log syntax
|
||||
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back rustc_mir \
|
||||
DEPS_rustc_plugin := rustc rustc_metadata syntax syntax_pos rustc_errors
|
||||
DEPS_rustc_privacy := rustc log syntax syntax_pos
|
||||
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
|
||||
log syntax serialize rustc_llvm rustc_platform_intrinsics \
|
||||
rustc_const_math rustc_const_eval rustc_incremental
|
||||
DEPS_rustc_incremental := rbml rustc serialize rustc_data_structures
|
||||
DEPS_rustc_save_analysis := rustc log syntax serialize
|
||||
DEPS_rustc_typeck := rustc syntax rustc_platform_intrinsics rustc_const_math \
|
||||
rustc_const_eval
|
||||
rustc_const_math rustc_const_eval rustc_incremental rustc_errors syntax_pos
|
||||
DEPS_rustc_incremental := rbml rustc syntax_pos serialize rustc_data_structures
|
||||
DEPS_rustc_save_analysis := rustc log syntax syntax_pos serialize
|
||||
DEPS_rustc_typeck := rustc syntax syntax_pos rustc_platform_intrinsics rustc_const_math \
|
||||
rustc_const_eval rustc_errors
|
||||
|
||||
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
|
||||
|
29
mk/llvm.mk
29
mk/llvm.mk
@ -27,31 +27,36 @@ endif
|
||||
|
||||
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
|
||||
ifeq ($(CFG_LLVM_ROOT),)
|
||||
|
||||
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)
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
$$(Q)$$(CFG_CMAKE) --build $$(CFG_LLVM_BUILD_DIR_$(1)) \
|
||||
--config $$(LLVM_BUILD_CONFIG_MODE)
|
||||
$$(Q)touch $$(LLVM_CONFIG_$(1))
|
||||
|
||||
clean-llvm$(1):
|
||||
|
||||
else
|
||||
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1))
|
||||
endif
|
||||
$$(Q)touch $$@
|
||||
|
||||
$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS) $$(LLVM_STAMP_$(1))
|
||||
@$$(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))
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
clean-llvm$(1):
|
||||
else
|
||||
clean-llvm$(1):
|
||||
@$$(call E, clean: llvm)
|
||||
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) clean
|
||||
|
||||
endif
|
||||
|
||||
else
|
||||
|
18
mk/main.mk
18
mk/main.mk
@ -13,12 +13,12 @@
|
||||
######################################################################
|
||||
|
||||
# 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'
|
||||
# NB Make sure it starts with a dot to conform to semver pre-release
|
||||
# versions (section 9)
|
||||
CFG_PRERELEASE_VERSION=.4
|
||||
CFG_PRERELEASE_VERSION=.3
|
||||
|
||||
# Append a version-dependent hash to each library, so we can install different
|
||||
# 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
|
||||
# from users enabling unstable features on the stable compiler.
|
||||
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: '//)
|
||||
endif
|
||||
|
||||
ifeq ($(CFG_RELEASE_CHANNEL),stable)
|
||||
# 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
|
||||
|
||||
ifdef SAVE_TEMPS
|
||||
CFG_RUSTC_FLAGS += --save-temps
|
||||
CFG_RUSTC_FLAGS += -C save-temps
|
||||
endif
|
||||
ifdef 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
|
||||
|
||||
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
|
||||
|
||||
|
159
mk/rt.mk
159
mk/rt.mk
@ -233,35 +233,98 @@ COMPRT_DEPS := $(wildcard \
|
||||
$(S)src/compiler-rt/*/*/*/*)
|
||||
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_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
|
||||
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
|
||||
@$$(call E, cmake: compiler-rt)
|
||||
$$(Q)cd "$$(COMPRT_BUILD_DIR_$(1))"; $$(CFG_CMAKE) "$(S)src/compiler-rt" \
|
||||
-DCMAKE_BUILD_TYPE=$$(LLVM_BUILD_CONFIG_MODE) \
|
||||
-DLLVM_CONFIG_PATH=$$(LLVM_CONFIG_$$(CFG_BUILD)) \
|
||||
-G"$$(CFG_CMAKE_GENERATOR)"
|
||||
$$(Q)$$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \
|
||||
--target lib/builtins/builtins \
|
||||
--config $$(LLVM_BUILD_CONFIG_MODE) \
|
||||
-- //v:m //nologo
|
||||
$$(Q)cp $$(COMPRT_BUILD_DIR_$(1))/lib/windows/$$(LLVM_BUILD_CONFIG_MODE)/clang_rt.builtins-$$(HOST_$(1)).lib $$@
|
||||
else
|
||||
COMPRT_CC_$(1) := $$(CC_$(1))
|
||||
COMPRT_AR_$(1) := $$(AR_$(1))
|
||||
# We chomp -Werror here because GCC warns about the type signature of
|
||||
# builtins not matching its own and the build fails. It's a bit hacky,
|
||||
# but what can we do, we're building libclang-rt using GCC ......
|
||||
COMPRT_CFLAGS_$(1) := $$(CFG_GCCISH_CFLAGS_$(1)) -Wno-error -std=c99
|
||||
COMPRT_ARCH_$(1) := $$(word 1,$$(subst -, ,$(1)))
|
||||
|
||||
# All this is to figure out the path to the compiler-rt bin
|
||||
ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
|
||||
COMPRT_DIR_$(1) := windows/Release
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(patsubst i%86,i386,$$(COMPRT_ARCH_$(1)))
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
|
||||
COMPRT_DIR_$(1) := windows
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring darwin,$(1)),darwin)
|
||||
COMPRT_DIR_$(1) := builtins
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins_$$(patsubst i686,i386,$$(COMPRT_ARCH_$(1)))_osx
|
||||
endif
|
||||
|
||||
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
|
||||
|
||||
ifeq ($$(findstring emscripten,$(1)),emscripten)
|
||||
@ -273,20 +336,26 @@ $$(COMPRT_LIB_$(1)):
|
||||
|
||||
else
|
||||
|
||||
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS)
|
||||
@$$(call E, make: compiler-rt)
|
||||
$$(Q)$$(MAKE) -C "$(S)src/compiler-rt" \
|
||||
ProjSrcRoot="$(S)src/compiler-rt" \
|
||||
ProjObjRoot="$$(abspath $$(COMPRT_BUILD_DIR_$(1)))" \
|
||||
CC='$$(COMPRT_CC_$(1))' \
|
||||
AR='$$(COMPRT_AR_$(1))' \
|
||||
RANLIB='$$(COMPRT_AR_$(1)) s' \
|
||||
CFLAGS="$$(COMPRT_CFLAGS_$(1))" \
|
||||
TargetTriple=$(1) \
|
||||
triple-builtins
|
||||
$$(Q)cp $$(COMPRT_BUILD_DIR_$(1))/triple/builtins/libcompiler_rt.a $$@
|
||||
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
|
||||
@$$(call E, cmake: compiler-rt)
|
||||
$$(Q)rm -rf $$(COMPRT_BUILD_DIR_$(1))
|
||||
$$(Q)mkdir $$(COMPRT_BUILD_DIR_$(1))
|
||||
$$(Q)cd "$$(COMPRT_BUILD_DIR_$(1))"; \
|
||||
$$(CFG_CMAKE) "$(S)src/compiler-rt" \
|
||||
-DCMAKE_BUILD_TYPE=$$(LLVM_BUILD_CONFIG_MODE) \
|
||||
-DLLVM_CONFIG_PATH=$$(LLVM_CONFIG_$$(CFG_BUILD)) \
|
||||
-DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=$(1) \
|
||||
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
|
||||
-DCOMPILER_RT_BUILD_EMUTLS=OFF \
|
||||
$$(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
|
||||
|
||||
################################################################################
|
||||
@ -310,20 +379,15 @@ ifeq ($$(findstring darwin,$$(OSTYPE_$(1))),darwin)
|
||||
$$(BACKTRACE_LIB_$(1)):
|
||||
touch $$@
|
||||
|
||||
else
|
||||
ifeq ($$(findstring ios,$$(OSTYPE_$(1))),ios)
|
||||
else ifeq ($$(findstring ios,$$(OSTYPE_$(1))),ios)
|
||||
# See comment above
|
||||
$$(BACKTRACE_LIB_$(1)):
|
||||
touch $$@
|
||||
else
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
else ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
# See comment above
|
||||
$$(BACKTRACE_LIB_$(1)):
|
||||
touch $$@
|
||||
else
|
||||
|
||||
ifeq ($$(findstring emscripten,$(1)),emscripten)
|
||||
else ifeq ($$(findstring emscripten,$(1)),emscripten)
|
||||
# FIXME: libbacktrace doesn't understand the emscripten triple
|
||||
$$(BACKTRACE_LIB_$(1)):
|
||||
touch $$@
|
||||
@ -376,10 +440,7 @@ $$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_BUILD_DIR_$(1))/Makefile $$(MKFILE_DEPS)
|
||||
INCDIR=$(S)src/libbacktrace
|
||||
$$(Q)cp $$(BACKTRACE_BUILD_DIR_$(1))/.libs/libbacktrace.a $$@
|
||||
|
||||
endif # endif for emscripten
|
||||
endif # endif for msvc
|
||||
endif # endif for ios
|
||||
endif # endif for darwin
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# libc/libunwind for musl
|
||||
|
@ -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)-ui-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
|
||||
|
||||
ifndef CFG_DISABLE_CODEGEN_TESTS
|
||||
|
@ -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
|
||||
responsible for downloading the stage0 compiler/Cargo binaries, and it then
|
||||
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
|
||||
sanity checks (compilers exist for example), and then start building the
|
||||
stage0 artifacts.
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import datetime
|
||||
import hashlib
|
||||
import os
|
||||
import shutil
|
||||
@ -18,6 +19,8 @@ import sys
|
||||
import tarfile
|
||||
import tempfile
|
||||
|
||||
from time import time
|
||||
|
||||
|
||||
def get(url, path, verbose=False):
|
||||
sha_url = url + ".sha256"
|
||||
@ -30,7 +33,7 @@ def get(url, path, verbose=False):
|
||||
download(sha_path, sha_url, verbose)
|
||||
download(temp_path, url, 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)
|
||||
finally:
|
||||
delete_if_present(sha_path)
|
||||
@ -44,7 +47,7 @@ def delete_if_present(path):
|
||||
|
||||
|
||||
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
|
||||
if sys.platform == 'win32':
|
||||
run(["PowerShell.exe", "/nologo", "-Command",
|
||||
@ -108,14 +111,18 @@ def run(args, verbose=False):
|
||||
|
||||
def stage0_data(rust_root):
|
||||
nightlies = os.path.join(rust_root, "src/stage0.txt")
|
||||
data = {}
|
||||
with open(nightlies, 'r') as nightlies:
|
||||
data = {}
|
||||
for line in nightlies.read().split("\n"):
|
||||
for line in nightlies:
|
||||
line = line.rstrip() # Strip newline character, '\n'
|
||||
if line.startswith("#") or line == '':
|
||||
continue
|
||||
a, b = line.split(": ", 1)
|
||||
data[a] = b
|
||||
return data
|
||||
return data
|
||||
|
||||
def format_build_time(duration):
|
||||
return str(datetime.timedelta(seconds=int(duration)))
|
||||
|
||||
class RustBuild:
|
||||
def download_stage0(self):
|
||||
@ -132,20 +139,20 @@ class RustBuild:
|
||||
if os.path.exists(self.bin_root()):
|
||||
shutil.rmtree(self.bin_root())
|
||||
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()
|
||||
tarball = os.path.join(rustc_cache, filename)
|
||||
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="rust-std-" + self.build,
|
||||
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()
|
||||
tarball = os.path.join(rustc_cache, filename)
|
||||
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)
|
||||
with open(self.rustc_stamp(), 'w') as f:
|
||||
f.write(self.stage0_rustc_date())
|
||||
@ -153,11 +160,11 @@ class RustBuild:
|
||||
if self.cargo().startswith(self.bin_root()) and \
|
||||
(not os.path.exists(self.cargo()) or self.cargo_out_of_date()):
|
||||
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()
|
||||
tarball = os.path.join(cargo_cache, filename)
|
||||
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)
|
||||
with open(self.cargo_stamp(), 'w') as f:
|
||||
f.write(self.stage0_cargo_date())
|
||||
@ -181,13 +188,13 @@ class RustBuild:
|
||||
return os.path.join(self.bin_root(), '.cargo-stamp')
|
||||
|
||||
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
|
||||
with open(self.rustc_stamp(), 'r') as f:
|
||||
return self.stage0_rustc_date() != f.read()
|
||||
|
||||
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
|
||||
with open(self.cargo_stamp(), 'r') as f:
|
||||
return self.stage0_cargo_date() != f.read()
|
||||
@ -234,8 +241,11 @@ class RustBuild:
|
||||
return ''
|
||||
|
||||
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["CARGO_TARGET_DIR"] = os.path.join(self.build_dir, "bootstrap")
|
||||
env["CARGO_TARGET_DIR"] = build_dir
|
||||
env["RUSTC"] = self.rustc()
|
||||
env["LD_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)
|
||||
|
||||
def run(self, args, env):
|
||||
proc = subprocess.Popen(args, env = env)
|
||||
proc = subprocess.Popen(args, env=env)
|
||||
ret = proc.wait()
|
||||
if ret != 0:
|
||||
sys.exit(ret)
|
||||
@ -261,20 +271,19 @@ class RustBuild:
|
||||
try:
|
||||
ostype = subprocess.check_output(['uname', '-s']).strip()
|
||||
cputype = subprocess.check_output(['uname', '-m']).strip()
|
||||
except FileNotFoundError:
|
||||
except (subprocess.CalledProcessError, WindowsError):
|
||||
if sys.platform == 'win32':
|
||||
return 'x86_64-pc-windows-msvc'
|
||||
else:
|
||||
err = "uname not found"
|
||||
if self.verbose:
|
||||
raise Exception(err)
|
||||
sys.exit(err)
|
||||
err = "uname not found"
|
||||
if self.verbose:
|
||||
raise Exception(err)
|
||||
sys.exit(err)
|
||||
|
||||
# Darwin's `uname -s` lies and always returns i386. We have to use
|
||||
# sysctl instead.
|
||||
if ostype == 'Darwin' and cputype == 'i686':
|
||||
sysctl = subprocess.check_output(['sysctl', 'hw.optional.x86_64'])
|
||||
if sysctl.contains(': 1'):
|
||||
if ': 1' in sysctl:
|
||||
cputype = 'x86_64'
|
||||
|
||||
# The goal here is to come up with the same triple as LLVM would,
|
||||
@ -335,11 +344,12 @@ class RustBuild:
|
||||
raise ValueError(err)
|
||||
sys.exit(err)
|
||||
|
||||
return cputype + '-' + ostype
|
||||
return "{}-{}".format(cputype, ostype)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Build rust')
|
||||
parser.add_argument('--config')
|
||||
parser.add_argument('--clean', action='store_true')
|
||||
parser.add_argument('-v', '--verbose', action='store_true')
|
||||
|
||||
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.build_dir = os.path.join(os.getcwd(), "build")
|
||||
rb.verbose = args.verbose
|
||||
rb.clean = args.clean
|
||||
|
||||
try:
|
||||
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._cargo_channel, rb._cargo_date = data['cargo'].split('-', 1)
|
||||
|
||||
start_time = time()
|
||||
|
||||
# Fetch/build the bootstrap
|
||||
rb.build = rb.build_triple()
|
||||
rb.download_stage0()
|
||||
@ -385,5 +398,9 @@ def main():
|
||||
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
|
||||
rb.run(args, env)
|
||||
|
||||
end_time = time()
|
||||
|
||||
print("Build completed in %s" % format_build_time(end_time - start_time))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -57,7 +57,9 @@ pub fn find(build: &mut Build) {
|
||||
let compiler = cfg.get_compiler();
|
||||
let ar = cc2ar(compiler.path(), target);
|
||||
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));
|
||||
}
|
||||
|
||||
@ -88,6 +90,7 @@ fn set_compiler(cfg: &mut gcc::Config,
|
||||
// compiler already takes into account the triple in question.
|
||||
t if t.contains("android") => {
|
||||
if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) {
|
||||
let target = target.replace("armv7", "arm");
|
||||
let compiler = format!("{}-{}", target, gnu_compiler);
|
||||
cfg.compiler(ndk.join("bin").join(compiler));
|
||||
}
|
||||
|
@ -23,6 +23,9 @@ use build_helper::output;
|
||||
use bootstrap::{dylib_path, dylib_path_var};
|
||||
|
||||
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.
|
||||
///
|
||||
@ -88,6 +91,7 @@ pub fn compiletest(build: &Build,
|
||||
target: &str,
|
||||
mode: &str,
|
||||
suite: &str) {
|
||||
println!("Check compiletest {} ({} -> {})", suite, compiler.host, target);
|
||||
let mut cmd = build.tool_cmd(compiler, "compiletest");
|
||||
|
||||
// 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("--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 {
|
||||
flags.push_str(" -O");
|
||||
flags.push("-O".to_string());
|
||||
}
|
||||
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());
|
||||
cmd.arg("--target-rustcflags").arg(format!("{} {}", flags, linkflag));
|
||||
|
||||
// FIXME: needs android support
|
||||
cmd.arg("--android-cross-path").arg("");
|
||||
let mut targetflags = build.rustc_flags(&target);
|
||||
targetflags.extend(flags);
|
||||
targetflags.push(format!("-Lnative={}",
|
||||
build.test_helpers_out(target).display()));
|
||||
cmd.arg("--target-rustcflags").arg(targetflags.join(" "));
|
||||
|
||||
// FIXME: CFG_PYTHON should probably be detected more robustly elsewhere
|
||||
let python_default = "python";
|
||||
@ -180,6 +186,16 @@ pub fn compiletest(build: &Build,
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@ -302,7 +318,97 @@ pub fn krate(build: &Build,
|
||||
let mut dylib_path = dylib_path();
|
||||
dylib_path.insert(0, build.sysroot_libdir(compiler, target));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,9 @@ use std::path::Path;
|
||||
use 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() {
|
||||
|
||||
let out = build.out.join(host);
|
||||
|
@ -65,8 +65,9 @@ pub struct Config {
|
||||
pub build: String,
|
||||
pub host: Vec<String>,
|
||||
pub target: Vec<String>,
|
||||
pub rustc: Option<String>,
|
||||
pub cargo: Option<String>,
|
||||
pub rustc: Option<PathBuf>,
|
||||
pub cargo: Option<PathBuf>,
|
||||
pub local_rebuild: bool,
|
||||
|
||||
// libstd features
|
||||
pub debug_jemalloc: bool,
|
||||
@ -207,8 +208,8 @@ impl Config {
|
||||
config.target.push(target.clone());
|
||||
}
|
||||
}
|
||||
config.rustc = build.rustc;
|
||||
config.cargo = build.cargo;
|
||||
config.rustc = build.rustc.map(PathBuf::from);
|
||||
config.cargo = build.cargo.map(PathBuf::from);
|
||||
set(&mut config.compiler_docs, build.compiler_docs);
|
||||
set(&mut config.docs, build.docs);
|
||||
|
||||
@ -315,6 +316,7 @@ impl Config {
|
||||
("RPATH", self.rust_rpath),
|
||||
("OPTIMIZE_TESTS", self.rust_optimize_tests),
|
||||
("DEBUGINFO_TESTS", self.rust_debuginfo_tests),
|
||||
("LOCAL_REBUILD", self.local_rebuild),
|
||||
}
|
||||
|
||||
match key {
|
||||
@ -366,17 +368,21 @@ impl Config {
|
||||
target.ndk = Some(PathBuf::from(value));
|
||||
}
|
||||
"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)
|
||||
.or_insert(Target::default());
|
||||
target.ndk = Some(PathBuf::from(value));
|
||||
}
|
||||
"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)
|
||||
.or_insert(Target::default());
|
||||
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"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
// installed
|
||||
t!(fs::create_dir_all(&overlay));
|
||||
let cp = |file: &str| {
|
||||
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
|
||||
if libdir != "bin" {
|
||||
t!(fs::create_dir_all(image.join(libdir)));
|
||||
for entry in t!(src.join(libdir).read_dir()).map(|e| t!(e)) {
|
||||
let name = entry.file_name();
|
||||
if let Some(s) = name.to_str() {
|
||||
@ -221,7 +219,6 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
|
||||
let cp = |file: &str| {
|
||||
install(&build.src.join(file), &image.join("share/doc/rust"), 0o644);
|
||||
};
|
||||
t!(fs::create_dir_all(&image.join("share/doc/rust")));
|
||||
cp("COPYRIGHT");
|
||||
cp("LICENSE-APACHE");
|
||||
cp("LICENSE-MIT");
|
||||
@ -289,6 +286,7 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
|
||||
|
||||
fn install(src: &Path, dstdir: &Path, perms: u32) {
|
||||
let dst = dstdir.join(src.file_name().unwrap());
|
||||
t!(fs::create_dir_all(dstdir));
|
||||
t!(fs::copy(src, &dst));
|
||||
chmod(&dst, perms);
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ pub struct Build {
|
||||
lldb_python_dir: Option<String>,
|
||||
|
||||
// Runtime state filled in later on
|
||||
cc: HashMap<String, (gcc::Tool, PathBuf)>,
|
||||
cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
|
||||
cxx: HashMap<String, gcc::Tool>,
|
||||
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
|
||||
/// build system, with each mod generating output in a different directory.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum Mode {
|
||||
/// This cargo is going to build the standard library, placing output in the
|
||||
/// "stageN-std" directory.
|
||||
@ -383,8 +384,7 @@ impl Build {
|
||||
"ui", "ui");
|
||||
}
|
||||
CheckDebuginfo { compiler } => {
|
||||
if target.target.contains("msvc") ||
|
||||
target.target.contains("android") {
|
||||
if target.target.contains("msvc") {
|
||||
// nothing to do
|
||||
} else if target.target.contains("apple") {
|
||||
check::compiletest(self, &compiler, target.target,
|
||||
@ -434,8 +434,14 @@ impl Build {
|
||||
target.target);
|
||||
}
|
||||
|
||||
AndroidCopyLibs { compiler } => {
|
||||
check::android_copy_libs(self, &compiler, target.target);
|
||||
}
|
||||
|
||||
// pseudo-steps
|
||||
Dist { .. } |
|
||||
Doc { .. } | // pseudo-steps
|
||||
Doc { .. } |
|
||||
CheckTarget { .. } |
|
||||
Check { .. } => {}
|
||||
}
|
||||
}
|
||||
@ -510,6 +516,14 @@ impl Build {
|
||||
.arg("-j").arg(self.jobs().to_string())
|
||||
.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
|
||||
// as our shim and then pass it some various options used to configure
|
||||
// how the actual compiler itself is called.
|
||||
@ -518,7 +532,7 @@ impl Build {
|
||||
// src/bootstrap/{rustc,rustdoc.rs}
|
||||
cargo.env("RUSTC", self.out.join("bootstrap/debug/rustc"))
|
||||
.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_CODEGEN_UNITS",
|
||||
self.config.rust_codegen_units.to_string())
|
||||
@ -541,7 +555,7 @@ impl Build {
|
||||
// FIXME: the guard against msvc shouldn't need to be here
|
||||
if !target.contains("msvc") {
|
||||
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(" "));
|
||||
}
|
||||
|
||||
@ -744,7 +758,7 @@ impl Build {
|
||||
// In stage0 we're using a previously released stable compiler, so we
|
||||
// use the stage0 bootstrap key. Otherwise we use our own build's
|
||||
// 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
|
||||
} else {
|
||||
&self.bootstrap_key
|
||||
@ -817,8 +831,8 @@ impl Build {
|
||||
}
|
||||
|
||||
/// Returns the path to the `ar` archive utility for the target specified.
|
||||
fn ar(&self, target: &str) -> &Path {
|
||||
&self.cc[target].1
|
||||
fn ar(&self, target: &str) -> Option<&Path> {
|
||||
self.cc[target].1.as_ref().map(|p| &**p)
|
||||
}
|
||||
|
||||
/// Returns the path to the C++ compiler for the target specified, may panic
|
||||
|
@ -20,14 +20,14 @@
|
||||
|
||||
use std::path::Path;
|
||||
use std::process::Command;
|
||||
use std::fs;
|
||||
use std::fs::{self, File};
|
||||
|
||||
use build_helper::output;
|
||||
use cmake;
|
||||
use gcc;
|
||||
|
||||
use build::Build;
|
||||
use build::util::{exe, staticlib, up_to_date};
|
||||
use build::util::{staticlib, up_to_date};
|
||||
|
||||
/// Compile LLVM for `target`.
|
||||
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.
|
||||
let dst = build.llvm_out(target);
|
||||
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);
|
||||
if fs::metadata(llvm_config).is_ok() {
|
||||
if fs::metadata(&done_stamp).is_ok() {
|
||||
return
|
||||
}
|
||||
|
||||
println!("Building LLVM for {}", target);
|
||||
|
||||
let _ = fs::remove_dir_all(&dst.join("build"));
|
||||
t!(fs::create_dir_all(&dst.join("build")));
|
||||
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 and libs on all platforms.
|
||||
cfg.build();
|
||||
|
||||
t!(File::create(&done_stamp));
|
||||
}
|
||||
|
||||
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 arch = target.split('-').next().unwrap();
|
||||
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 mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
|
||||
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
|
||||
// it's needed to get the initial configure to work on all platforms.
|
||||
.define("CMAKE_C_COMPILER", build.cc(target))
|
||||
.define("CMAKE_CXX_COMPILER", build.cc(target))
|
||||
.build_target(&build_target);
|
||||
.define("CMAKE_CXX_COMPILER", build.cc(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();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,9 @@ pub fn check(build: &mut Build) {
|
||||
// also build some C++ shims for LLVM so we need a C++ compiler.
|
||||
for target in build.config.target.iter() {
|
||||
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() {
|
||||
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() {
|
||||
|
@ -102,6 +102,7 @@ macro_rules! targets {
|
||||
// Steps for running tests. The 'check' target is just a pseudo
|
||||
// target to depend on a bunch of others.
|
||||
(check, Check { stage: u32, compiler: Compiler<'a> }),
|
||||
(check_target, CheckTarget { stage: u32, compiler: Compiler<'a> }),
|
||||
(check_linkcheck, CheckLinkcheck { stage: u32 }),
|
||||
(check_cargotest, CheckCargoTest { stage: u32 }),
|
||||
(check_tidy, CheckTidy { stage: u32 }),
|
||||
@ -138,6 +139,9 @@ macro_rules! targets {
|
||||
(dist_mingw, DistMingw { _dummy: () }),
|
||||
(dist_rustc, DistRustc { stage: u32 }),
|
||||
(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)]
|
||||
}
|
||||
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_full(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_test(compiler),
|
||||
self.check_crate_rustc(compiler),
|
||||
self.check_codegen(compiler),
|
||||
self.check_codegen_units(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),
|
||||
]
|
||||
];
|
||||
|
||||
// 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 } => {
|
||||
vec![self.tool_linkchecker(stage), self.doc(stage)]
|
||||
@ -437,16 +484,20 @@ impl<'a> Step<'a> {
|
||||
Source::CheckCFail { compiler } |
|
||||
Source::CheckRPassValgrind { compiler } |
|
||||
Source::CheckRPass { compiler } => {
|
||||
vec![
|
||||
let mut base = vec![
|
||||
self.libtest(compiler),
|
||||
self.tool_compiletest(compiler.stage),
|
||||
self.target(compiler.host).tool_compiletest(compiler.stage),
|
||||
self.test_helpers(()),
|
||||
]
|
||||
];
|
||||
if self.target.contains("android") {
|
||||
base.push(self.android_copy_libs(compiler));
|
||||
}
|
||||
base
|
||||
}
|
||||
Source::CheckDebuginfo { compiler } => {
|
||||
vec![
|
||||
self.libtest(compiler),
|
||||
self.tool_compiletest(compiler.stage),
|
||||
self.target(compiler.host).tool_compiletest(compiler.stage),
|
||||
self.test_helpers(()),
|
||||
self.debugger_scripts(compiler.stage),
|
||||
]
|
||||
@ -459,13 +510,14 @@ impl<'a> Step<'a> {
|
||||
Source::CheckPrettyRPassValgrind { compiler } |
|
||||
Source::CheckRMake { compiler } => {
|
||||
vec![self.librustc(compiler),
|
||||
self.tool_compiletest(compiler.stage)]
|
||||
self.target(compiler.host).tool_compiletest(compiler.stage)]
|
||||
}
|
||||
Source::CheckDocs { compiler } => {
|
||||
vec![self.libstd(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 } => {
|
||||
vec![self.libtest(compiler)]
|
||||
@ -529,6 +581,10 @@ impl<'a> Step<'a> {
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
Source::AndroidCopyLibs { compiler } => {
|
||||
vec![self.libtest(compiler)]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,11 @@ all:
|
||||
clean:
|
||||
$(Q)$(BOOTSTRAP) --clean
|
||||
|
||||
rustc-stage1:
|
||||
$(Q)$(BOOTSTRAP) --step libtest --stage 1
|
||||
rustc-stage2:
|
||||
$(Q)$(BOOTSTRAP) --step libtest --stage 2
|
||||
|
||||
docs: doc
|
||||
doc:
|
||||
$(Q)$(BOOTSTRAP) --step doc
|
||||
|
@ -39,9 +39,11 @@ pub fn gnu_target(target: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cc2ar(cc: &Path, target: &str) -> PathBuf {
|
||||
if target.contains("musl") || target.contains("msvc") {
|
||||
PathBuf::from("ar")
|
||||
pub fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
|
||||
if target.contains("msvc") {
|
||||
None
|
||||
} else if target.contains("musl") {
|
||||
Some(PathBuf::from("ar"))
|
||||
} else {
|
||||
let parent = cc.parent().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) {
|
||||
let mut file = file[..idx].to_owned();
|
||||
file.push_str("ar");
|
||||
return parent.join(&file);
|
||||
return Some(parent.join(&file));
|
||||
}
|
||||
}
|
||||
parent.join(file)
|
||||
Some(parent.join(file))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,10 @@ if (NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
# Windows where we need to use clang-cl instead.
|
||||
if(NOT MSVC)
|
||||
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
|
||||
set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
|
||||
else()
|
||||
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang.exe)
|
||||
set(COMPILER_RT_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++.exe)
|
||||
endif()
|
||||
else()
|
||||
# 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)
|
||||
# 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_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "C++ Compiler to use for testing")
|
||||
|
||||
if (NOT LLVM_CONFIG_PATH)
|
||||
find_program(LLVM_CONFIG_PATH "llvm-config"
|
||||
@ -189,6 +192,8 @@ else()
|
||||
endif()
|
||||
|
||||
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.
|
||||
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_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_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_LTO_FLAG -fno-lto SANITIZER_COMMON_CFLAGS)
|
||||
|
||||
|
@ -19,7 +19,7 @@ function(add_compiler_rt_object_libraries name)
|
||||
set(libname "${name}.${os}")
|
||||
set(libnames ${libnames} ${libname})
|
||||
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()
|
||||
else()
|
||||
foreach(arch ${LIB_ARCHS})
|
||||
@ -87,7 +87,7 @@ function(add_compiler_rt_runtime name type)
|
||||
set(libname "${name}_${os}_dynamic")
|
||||
set(extra_linkflags_${libname} ${DARWIN_${os}_LINKFLAGS} ${LIB_LINKFLAGS})
|
||||
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})
|
||||
list(APPEND libnames ${libname})
|
||||
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
|
||||
OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
|
||||
endif()
|
||||
|
||||
if(type STREQUAL "SHARED")
|
||||
rt_externalize_debuginfo(${libname})
|
||||
endif()
|
||||
endforeach()
|
||||
if(LIB_PARENT_TARGET)
|
||||
add_dependencies(${LIB_PARENT_TARGET} ${libnames})
|
||||
@ -284,12 +288,14 @@ macro(add_custom_libcxx name prefix)
|
||||
ExternalProject_Add(${name}
|
||||
PREFIX ${prefix}
|
||||
SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH}
|
||||
CMAKE_ARGS -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}
|
||||
-DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_COMPILER}
|
||||
CMAKE_ARGS -DCMAKE_MAKE_PROGRAM:STRING=${CMAKE_MAKE_PROGRAM}
|
||||
-DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}
|
||||
-DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}
|
||||
-DCMAKE_C_FLAGS=${LIBCXX_CFLAGS}
|
||||
-DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS}
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
|
||||
-DLLVM_PATH=${LLVM_MAIN_SRC_DIR}
|
||||
LOG_BUILD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_INSTALL 1
|
||||
@ -309,3 +315,24 @@ macro(add_custom_libcxx name prefix)
|
||||
DEPENDS ${LIBCXX_DEPS}
|
||||
)
|
||||
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()
|
||||
|
@ -24,19 +24,6 @@ function(translate_msvc_cflags out_flags msvc_flags)
|
||||
set(${out_flags} "${clang_flags}" PARENT_SCOPE)
|
||||
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
|
||||
# a provided compile flags and dependenices.
|
||||
# clang_compile(<object> <source>
|
||||
|
@ -46,6 +46,11 @@ endfunction()
|
||||
# This function takes an OS and a list of architectures and identifies the
|
||||
# subset of the architectures list that the installed toolchain can target.
|
||||
function(darwin_test_archs os valid_archs)
|
||||
if(${valid_archs})
|
||||
message(STATUS "Using cached valid architectures for ${os}.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(archs ${ARGN})
|
||||
message(STATUS "Finding valid architectures for ${os}...")
|
||||
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)
|
||||
if(${CAN_TARGET_${os}_${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()
|
||||
endforeach()
|
||||
set(${valid_archs} ${working_archs} PARENT_SCOPE)
|
||||
set(${valid_archs} ${working_archs}
|
||||
CACHE STRING "List of valid architectures for platform ${os}.")
|
||||
endfunction()
|
||||
|
||||
# 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.
|
||||
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(
|
||||
COMMAND sysctl hw.cpusubtype
|
||||
OUTPUT_VARIABLE SUBTYPE)
|
||||
@ -159,11 +169,43 @@ macro(darwin_add_builtin_library name suffix)
|
||||
"PARENT_TARGET;OS;ARCH"
|
||||
"SOURCES;CFLAGS;DEFS"
|
||||
${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}")
|
||||
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}
|
||||
-isysroot ${DARWIN_${LIB_OS}_SYSROOT}
|
||||
${DARWIN_${LIB_OS}_BUILTIN_MIN_VER_FLAG}
|
||||
${sysroot_flag}
|
||||
${DARWIN_${REF_OS}_BUILTIN_MIN_VER_FLAG}
|
||||
${LIB_CFLAGS})
|
||||
set_property(TARGET ${libname} APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS ${LIB_DEFS})
|
||||
@ -186,18 +228,22 @@ function(darwin_lipo_libs name)
|
||||
"PARENT_TARGET;OUTPUT_DIR;INSTALL_DIR"
|
||||
"LIPO_FLAGS;DEPENDS"
|
||||
${ARGN})
|
||||
add_custom_command(OUTPUT ${LIB_OUTPUT_DIR}/lib${name}.a
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}
|
||||
COMMAND lipo -output
|
||||
${LIB_OUTPUT_DIR}/lib${name}.a
|
||||
-create ${LIB_LIPO_FLAGS}
|
||||
DEPENDS ${LIB_DEPENDS}
|
||||
)
|
||||
add_custom_target(${name}
|
||||
DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a)
|
||||
add_dependencies(${LIB_PARENT_TARGET} ${name})
|
||||
install(FILES ${LIB_OUTPUT_DIR}/lib${name}.a
|
||||
DESTINATION ${LIB_INSTALL_DIR})
|
||||
if(LIB_DEPENDS AND LIB_LIPO_FLAGS)
|
||||
add_custom_command(OUTPUT ${LIB_OUTPUT_DIR}/lib${name}.a
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}
|
||||
COMMAND lipo -output
|
||||
${LIB_OUTPUT_DIR}/lib${name}.a
|
||||
-create ${LIB_LIPO_FLAGS}
|
||||
DEPENDS ${LIB_DEPENDS}
|
||||
)
|
||||
add_custom_target(${name}
|
||||
DEPENDS ${LIB_OUTPUT_DIR}/lib${name}.a)
|
||||
add_dependencies(${LIB_PARENT_TARGET} ${name})
|
||||
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()
|
||||
|
||||
# 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)
|
||||
if(_found ${filter_action} ${filter_value})
|
||||
list(REMOVE_ITEM intermediate ${_file})
|
||||
elseif(${_file} MATCHES ".*/.*\\.S")
|
||||
elseif(${_file} MATCHES ".*/.*\\.S" OR ${_file} MATCHES ".*/.*\\.c")
|
||||
get_filename_component(_name ${_file} NAME)
|
||||
string(REPLACE ".S" ".c" _cname "${_name}")
|
||||
list(REMOVE_ITEM intermediate ${_cname})
|
||||
@ -230,11 +276,18 @@ function(darwin_filter_builtin_sources output_var exclude_or_include excluded_li
|
||||
endfunction()
|
||||
|
||||
function(darwin_add_eprintf_library)
|
||||
cmake_parse_arguments(LIB
|
||||
""
|
||||
""
|
||||
"CFLAGS"
|
||||
${ARGN})
|
||||
|
||||
add_library(clang_rt.eprintf STATIC eprintf.c)
|
||||
set_target_compile_flags(clang_rt.eprintf
|
||||
-isysroot ${DARWIN_osx_SYSROOT}
|
||||
${DARWIN_osx_BUILTIN_MIN_VER_FLAG}
|
||||
-arch i386)
|
||||
-arch i386
|
||||
${LIB_CFLAGS})
|
||||
set_target_properties(clang_rt.eprintf PROPERTIES
|
||||
OUTPUT_NAME clang_rt.eprintf${COMPILER_RT_OS_SUFFIX})
|
||||
set_target_properties(clang_rt.eprintf PROPERTIES
|
||||
@ -251,24 +304,17 @@ endfunction()
|
||||
macro(darwin_add_builtin_libraries)
|
||||
set(DARWIN_EXCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Darwin-excludes)
|
||||
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
foreach(type ${CMAKE_CONFIGURATION_TYPES})
|
||||
set(CMAKE_C_FLAGS_${type} -O3)
|
||||
set(CMAKE_CXX_FLAGS_${type} -O3)
|
||||
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(CFLAGS "-fPIC -O3 -fvisibility=hidden -DVISIBILITY_HIDDEN -Wall -fomit-frame-pointer")
|
||||
set(CMAKE_C_FLAGS "")
|
||||
set(CMAKE_CXX_FLAGS "")
|
||||
set(CMAKE_ASM_FLAGS "")
|
||||
|
||||
set(PROFILE_SOURCES ../profile/InstrProfiling
|
||||
../profile/InstrProfilingBuffer
|
||||
../profile/InstrProfilingPlatformDarwin)
|
||||
../profile/InstrProfilingPlatformDarwin
|
||||
../profile/InstrProfilingWriter)
|
||||
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})
|
||||
darwin_find_excluded_builtins_list(${arch}_${os}_EXCLUDED_BUILTINS
|
||||
OS ${os}
|
||||
@ -283,7 +329,7 @@ macro(darwin_add_builtin_libraries)
|
||||
OS ${os}
|
||||
ARCH ${arch}
|
||||
SOURCES ${filtered_sources}
|
||||
CFLAGS -arch ${arch}
|
||||
CFLAGS ${CFLAGS} -arch ${arch}
|
||||
PARENT_TARGET builtins)
|
||||
endforeach()
|
||||
|
||||
@ -306,7 +352,7 @@ macro(darwin_add_builtin_libraries)
|
||||
OS ${os}
|
||||
ARCH ${arch}
|
||||
SOURCES ${filtered_sources} ${PROFILE_SOURCES}
|
||||
CFLAGS -arch ${arch} -mkernel
|
||||
CFLAGS ${CFLAGS} -arch ${arch} -mkernel
|
||||
DEFS KERNEL_USE
|
||||
PARENT_TARGET builtins)
|
||||
endforeach()
|
||||
@ -323,7 +369,7 @@ macro(darwin_add_builtin_libraries)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
darwin_add_eprintf_library()
|
||||
darwin_add_eprintf_library(CFLAGS ${CFLAGS})
|
||||
|
||||
# We put the x86 sim slices into the archives for their base OS
|
||||
foreach (os ${ARGN})
|
||||
@ -339,96 +385,99 @@ macro(darwin_add_builtin_libraries)
|
||||
darwin_add_embedded_builtin_libraries()
|
||||
endmacro()
|
||||
|
||||
function(darwin_add_embedded_builtin_libraries)
|
||||
set(MACHO_SYM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/macho_embedded)
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
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")
|
||||
|
||||
macro(darwin_add_embedded_builtin_libraries)
|
||||
# this is a hacky opt-out. If you can't target both intel and arm
|
||||
# architectures we bail here.
|
||||
set(DARWIN_SOFT_FLOAT_ARCHS armv6m armv7m armv7em armv7)
|
||||
set(DARWIN_HARD_FLOAT_ARCHS armv7em armv7 i386 x86_64)
|
||||
|
||||
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!")
|
||||
set(DARWIN_HARD_FLOAT_ARCHS armv7em armv7)
|
||||
if(COMPILER_RT_SUPPORTED_ARCH MATCHES ".*armv.*")
|
||||
list(FIND COMPILER_RT_SUPPORTED_ARCH i386 i386_idx)
|
||||
if(i386_idx GREATER -1)
|
||||
list(APPEND DARWIN_HARD_FLOAT_ARCHS i386)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
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(DARWIN_macho_embedded_BUILTIN_MIN_VER_FLAG ${DARWIN_osx_BUILTIN_MIN_VER_FLAG})
|
||||
set(float_flag)
|
||||
if(${arch} MATCHES "^arm")
|
||||
set(DARWIN_macho_embedded_SYSROOT ${DARWIN_ios_SYSROOT})
|
||||
# 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 -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})
|
||||
list(FIND COMPILER_RT_SUPPORTED_ARCH x86_64 x86_64_idx)
|
||||
if(x86_64_idx GREATER -1)
|
||||
list(APPEND DARWIN_HARD_FLOAT_ARCHS x86_64)
|
||||
endif()
|
||||
|
||||
set(MACHO_SYM_DIR ${CMAKE_CURRENT_SOURCE_DIR}/macho_embedded)
|
||||
|
||||
set(CFLAGS "-Oz -Wall -fomit-frame-pointer -ffreestanding")
|
||||
set(CMAKE_C_FLAGS "")
|
||||
set(CMAKE_CXX_FLAGS "")
|
||||
set(CMAKE_ASM_FLAGS "")
|
||||
|
||||
set(SOFT_FLOAT_FLAG -mfloat-abi=soft)
|
||||
set(HARD_FLOAT_FLAG -mfloat-abi=hard)
|
||||
|
||||
set(ENABLE_PIC Off)
|
||||
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_i386 "-march=pentium")
|
||||
|
||||
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()
|
||||
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()
|
||||
|
@ -58,7 +58,7 @@ macro(append_have_file_definition filename varname list)
|
||||
list(APPEND ${list} "${varname}=${${varname}}")
|
||||
endmacro()
|
||||
|
||||
macro(list_union output input1 input2)
|
||||
macro(list_intersect output input1 input2)
|
||||
set(${output})
|
||||
foreach(it ${${input1}})
|
||||
list(FIND ${input2} ${it} index)
|
||||
|
@ -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(-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(-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(/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)
|
||||
|
||||
# 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(rt shm_open "" COMPILER_RT_HAS_LIBRT)
|
||||
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(__mips__ "" __MIPS)
|
||||
check_symbol_exists(__mips64__ "" __MIPS64)
|
||||
check_symbol_exists(__wasm32__ "" __WEBASSEMBLY32)
|
||||
check_symbol_exists(__wasm64__ "" __WEBASSEMBLY64)
|
||||
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)
|
||||
add_default_target_arch(aarch64)
|
||||
elseif(__X86_64)
|
||||
@ -157,6 +167,10 @@ macro(detect_target_arch)
|
||||
add_default_target_arch(mips64)
|
||||
elseif(__MIPS)
|
||||
add_default_target_arch(mips)
|
||||
elseif(__WEBASSEMBLY32)
|
||||
add_default_target_arch(wasm32)
|
||||
elseif(__WEBASSEMBLY64)
|
||||
add_default_target_arch(wasm64)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@ -191,6 +205,7 @@ elseif(NOT APPLE) # Supported archs for Apple platforms are generated later
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "powerpc")
|
||||
TEST_BIG_ENDIAN(HOST_IS_BIG_ENDIAN)
|
||||
if(HOST_IS_BIG_ENDIAN)
|
||||
test_target_arch(powerpc "" "-m32")
|
||||
test_target_arch(powerpc64 "" "-m64")
|
||||
else()
|
||||
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(mips64 "" "-mips64r2" "--target=mips64-linux-gnu" "-mabi=n64")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "arm")
|
||||
if("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES "eabihf")
|
||||
test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard")
|
||||
if("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES "armv7")
|
||||
test_target_arch(armv7 "" "${CMAKE_C_FLAGS}")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" MATCHES "eabihf")
|
||||
test_target_arch(armhf "" "${CMAKE_C_FLAGS}")
|
||||
else()
|
||||
test_target_arch(arm "" "-march=armv7-a" "-mfloat-abi=soft")
|
||||
test_target_arch(arm "" "${CMAKE_C_FLAGS}")
|
||||
endif()
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32")
|
||||
test_target_arch(aarch32 "" "-march=armv8-a")
|
||||
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64")
|
||||
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()
|
||||
set(COMPILER_RT_OS_SUFFIX "")
|
||||
endif()
|
||||
@ -250,12 +271,15 @@ function(get_target_flags_for_arch arch out_var)
|
||||
endfunction()
|
||||
|
||||
set(ARM64 aarch64)
|
||||
set(ARM32 arm armhf)
|
||||
set(ARM32 arm armhf armv7)
|
||||
set(X86 i386 i686)
|
||||
set(X86_64 x86_64)
|
||||
set(MIPS32 mips mipsel)
|
||||
set(MIPS64 mips64 mips64el)
|
||||
set(PPC powerpc)
|
||||
set(PPC64 powerpc64 powerpc64le)
|
||||
set(WASM32 wasm32)
|
||||
set(WASM64 wasm64)
|
||||
|
||||
if(APPLE)
|
||||
set(ARM64 arm64)
|
||||
@ -264,7 +288,7 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
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}
|
||||
${ARM32} ${ARM64} ${MIPS32} ${MIPS64})
|
||||
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_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64}
|
||||
${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}
|
||||
${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)
|
||||
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_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_iossim_SYSROOT iphonesimulator)
|
||||
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
|
||||
# be 10.8 or higher.
|
||||
@ -318,6 +388,11 @@ if(APPLE)
|
||||
-lc++
|
||||
-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
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
-mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})
|
||||
@ -363,98 +438,102 @@ if(APPLE)
|
||||
list(APPEND BUILTIN_SUPPORTED_OS 10.4)
|
||||
endif()
|
||||
|
||||
if(DARWIN_iossim_SYSROOT)
|
||||
set(DARWIN_iossim_CFLAGS
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
-mios-simulator-version-min=7.0
|
||||
-isysroot ${DARWIN_iossim_SYSROOT})
|
||||
set(DARWIN_iossim_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
-mios-simulator-version-min=7.0
|
||||
-isysroot ${DARWIN_iossim_SYSROOT})
|
||||
set(DARWIN_iossim_BUILTIN_MIN_VER 6.0)
|
||||
set(DARWIN_iossim_BUILTIN_MIN_VER_FLAG
|
||||
-mios-simulator-version-min=${DARWIN_iossim_BUILTIN_MIN_VER})
|
||||
foreach(platform ${DARWIN_EMBEDDED_PLATFORMS})
|
||||
if(DARWIN_${platform}sim_SYSROOT)
|
||||
set(DARWIN_${platform}sim_CFLAGS
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_iossim_SYSROOT})
|
||||
set(DARWIN_${platform}sim_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_${platform}sim_SYSROOT})
|
||||
set(DARWIN_${platform}sim_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)
|
||||
darwin_test_archs(iossim
|
||||
DARWIN_iossim_ARCHS
|
||||
${toolchain_arches})
|
||||
message(STATUS "iOS Simulator supported arches: ${DARWIN_iossim_ARCHS}")
|
||||
if(DARWIN_iossim_ARCHS)
|
||||
list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim)
|
||||
set(DARWIN_${platform}sim_SKIP_CC_KEXT On)
|
||||
darwin_test_archs(${platform}sim
|
||||
DARWIN_${platform}sim_ARCHS
|
||||
${toolchain_arches})
|
||||
message(STATUS "${platform} Simulator supported arches: ${DARWIN_${platform}sim_ARCHS}")
|
||||
if(DARWIN_iossim_ARCHS)
|
||||
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()
|
||||
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)
|
||||
set(DARWIN_ios_CFLAGS
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
-miphoneos-version-min=7.0
|
||||
-isysroot ${DARWIN_ios_SYSROOT})
|
||||
set(DARWIN_ios_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
-miphoneos-version-min=7.0
|
||||
-isysroot ${DARWIN_ios_SYSROOT})
|
||||
set(DARWIN_ios_BUILTIN_MIN_VER 6.0)
|
||||
set(DARWIN_ios_BUILTIN_MIN_VER_FLAG
|
||||
-miphoneos-version-min=${DARWIN_ios_BUILTIN_MIN_VER})
|
||||
if(DARWIN_${platform}_SYSROOT)
|
||||
set(DARWIN_${platform}_CFLAGS
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_${platform}_SYSROOT})
|
||||
set(DARWIN_${platform}_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_${platform}_SYSROOT})
|
||||
|
||||
darwin_test_archs(ios
|
||||
DARWIN_ios_ARCHS
|
||||
${toolchain_arches})
|
||||
message(STATUS "iOS supported arches: ${DARWIN_ios_ARCHS}")
|
||||
if(DARWIN_ios_ARCHS)
|
||||
list(APPEND SANITIZER_COMMON_SUPPORTED_OS ios)
|
||||
list(APPEND BUILTIN_SUPPORTED_OS ios)
|
||||
list(APPEND PROFILE_SUPPORTED_OS ios)
|
||||
list(APPEND BUILTIN_SUPPORTED_OS iossim)
|
||||
darwin_test_archs(${platform}
|
||||
DARWIN_${platform}_ARCHS
|
||||
${toolchain_arches})
|
||||
message(STATUS "${platform} supported arches: ${DARWIN_${platform}_ARCHS}")
|
||||
if(DARWIN_${platform}_ARCHS)
|
||||
list(APPEND SANITIZER_COMMON_SUPPORTED_OS ${platform})
|
||||
list(APPEND BUILTIN_SUPPORTED_OS ${platform})
|
||||
list(APPEND PROFILE_SUPPORTED_OS ${platform})
|
||||
endif()
|
||||
foreach(arch ${DARWIN_${platform}_ARCHS})
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
set(CAN_TARGET_${arch} 1)
|
||||
endforeach()
|
||||
endif()
|
||||
foreach(arch ${DARWIN_ios_ARCHS})
|
||||
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
|
||||
set(CAN_TARGET_${arch} 1)
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# for list_union
|
||||
# for list_intersect
|
||||
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
|
||||
COMPILER_RT_SUPPORTED_ARCH
|
||||
)
|
||||
set(LSAN_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
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_union(DFSAN_SUPPORTED_ARCH
|
||||
list_intersect(DFSAN_SUPPORTED_ARCH
|
||||
ALL_DFSAN_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_union(LSAN_SUPPORTED_ARCH
|
||||
list_intersect(LSAN_SUPPORTED_ARCH
|
||||
ALL_LSAN_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_union(MSAN_SUPPORTED_ARCH
|
||||
list_intersect(MSAN_SUPPORTED_ARCH
|
||||
ALL_MSAN_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_union(PROFILE_SUPPORTED_ARCH
|
||||
list_intersect(PROFILE_SUPPORTED_ARCH
|
||||
ALL_PROFILE_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_union(TSAN_SUPPORTED_ARCH
|
||||
list_intersect(TSAN_SUPPORTED_ARCH
|
||||
ALL_TSAN_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_union(UBSAN_SUPPORTED_ARCH
|
||||
list_intersect(UBSAN_SUPPORTED_ARCH
|
||||
ALL_UBSAN_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_union(SAFESTACK_SUPPORTED_ARCH
|
||||
list_intersect(SAFESTACK_SUPPORTED_ARCH
|
||||
ALL_SAFESTACK_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
list_intersect(CFI_SUPPORTED_ARCH
|
||||
ALL_CFI_SUPPORTED_ARCH
|
||||
SANITIZER_COMMON_SUPPORTED_ARCH)
|
||||
else()
|
||||
# Architectures supported by compiler-rt libraries.
|
||||
filter_available_targets(BUILTIN_SUPPORTED_ARCH
|
||||
@ -476,6 +555,7 @@ else()
|
||||
filter_available_targets(UBSAN_SUPPORTED_ARCH ${ALL_UBSAN_SUPPORTED_ARCH})
|
||||
filter_available_targets(SAFESTACK_SUPPORTED_ARCH
|
||||
${ALL_SAFESTACK_SUPPORTED_ARCH})
|
||||
filter_available_targets(CFI_SUPPORTED_ARCH ${ALL_CFI_SUPPORTED_ARCH})
|
||||
endif()
|
||||
|
||||
message(STATUS "Compiler-RT supported architectures: ${COMPILER_RT_SUPPORTED_ARCH}")
|
||||
@ -538,26 +618,19 @@ else()
|
||||
endif()
|
||||
|
||||
if (PROFILE_SUPPORTED_ARCH AND
|
||||
OS_NAME MATCHES "Darwin|Linux|FreeBSD")
|
||||
OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows")
|
||||
set(COMPILER_RT_HAS_PROFILE TRUE)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_PROFILE FALSE)
|
||||
endif()
|
||||
|
||||
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)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_TSAN FALSE)
|
||||
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
|
||||
OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows")
|
||||
set(COMPILER_RT_HAS_UBSAN TRUE)
|
||||
@ -565,17 +638,16 @@ else()
|
||||
set(COMPILER_RT_HAS_UBSAN FALSE)
|
||||
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
|
||||
OS_NAME MATCHES "Darwin|Linux|FreeBSD")
|
||||
set(COMPILER_RT_HAS_SAFESTACK TRUE)
|
||||
else()
|
||||
set(COMPILER_RT_HAS_SAFESTACK FALSE)
|
||||
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()
|
||||
|
@ -125,9 +125,11 @@ extern "C" {
|
||||
// to know what is being passed to libc functions, e.g. memcmp.
|
||||
// FIXME: implement more hooks.
|
||||
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,
|
||||
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
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -41,6 +41,13 @@ extern "C" {
|
||||
// Some of the entries in *data will be zero.
|
||||
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.
|
||||
// Rather than exposing the counter values to the user we instead map
|
||||
// the counters to a bitset.
|
||||
|
@ -19,8 +19,6 @@ if(COMPILER_RT_BUILD_SANITIZERS)
|
||||
add_subdirectory(ubsan)
|
||||
endif()
|
||||
|
||||
add_subdirectory(cfi)
|
||||
|
||||
if(COMPILER_RT_HAS_ASAN)
|
||||
add_subdirectory(asan)
|
||||
endif()
|
||||
@ -45,4 +43,8 @@ if(COMPILER_RT_BUILD_SANITIZERS)
|
||||
if(COMPILER_RT_HAS_SAFESTACK)
|
||||
add_subdirectory(safestack)
|
||||
endif()
|
||||
|
||||
if(COMPILER_RT_HAS_CFI)
|
||||
add_subdirectory(cfi)
|
||||
endif()
|
||||
endif()
|
||||
|
1
src/compiler-rt/lib/asan/.clang-format
Normal file
1
src/compiler-rt/lib/asan/.clang-format
Normal file
@ -0,0 +1 @@
|
||||
BasedOnStyle: Google
|
@ -23,4 +23,4 @@ from the root of your CMake build tree:
|
||||
make check-asan
|
||||
|
||||
For more instructions see:
|
||||
http://code.google.com/p/address-sanitizer/wiki/HowToBuild
|
||||
https://github.com/google/sanitizers/wiki/AddressSanitizerHowToBuild
|
||||
|
@ -61,11 +61,6 @@ static struct AsanDeactivatedFlags {
|
||||
parser.ParseString(env);
|
||||
}
|
||||
|
||||
// Override from getprop asan.options.
|
||||
char buf[100];
|
||||
GetExtraActivationFlags(buf, sizeof(buf));
|
||||
parser.ParseString(buf);
|
||||
|
||||
SetVerbosity(cf.verbosity);
|
||||
|
||||
if (Verbosity()) ReportUnrecognizedFlags();
|
||||
|
@ -116,14 +116,6 @@ void InitializeFlags() {
|
||||
ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
|
||||
#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);
|
||||
|
||||
// TODO(eugenis): dump all flags at verbosity>=2?
|
||||
|
@ -44,9 +44,6 @@ ASAN_FLAG(
|
||||
"to find more errors.")
|
||||
ASAN_FLAG(bool, replace_intrin, true,
|
||||
"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,
|
||||
"Enables stack-use-after-return checking at run-time.")
|
||||
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.*.")
|
||||
ASAN_FLAG(bool, unmap_shadow_on_exit, false,
|
||||
"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,
|
||||
"Print various statistics after printing an error message or if "
|
||||
"atexit=1.")
|
||||
@ -98,8 +96,8 @@ ASAN_FLAG(bool, poison_array_cookie, true,
|
||||
"Poison (or not) the array cookie after operator new[].")
|
||||
|
||||
// Turn off alloc/dealloc mismatch checker on Mac and Windows for now.
|
||||
// https://code.google.com/p/address-sanitizer/issues/detail?id=131
|
||||
// https://code.google.com/p/address-sanitizer/issues/detail?id=309
|
||||
// https://github.com/google/sanitizers/issues/131
|
||||
// https://github.com/google/sanitizers/issues/309
|
||||
// TODO(glider,timurrrr): Fix known issues and enable this back.
|
||||
ASAN_FLAG(bool, alloc_dealloc_mismatch,
|
||||
(SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0),
|
||||
@ -125,8 +123,8 @@ ASAN_FLAG(
|
||||
"The bigger the value the harder we try.")
|
||||
ASAN_FLAG(
|
||||
bool, detect_container_overflow, true,
|
||||
"If true, honor the container overflow annotations. "
|
||||
"See https://code.google.com/p/address-sanitizer/wiki/ContainerOverflow")
|
||||
"If true, honor the container overflow annotations. See "
|
||||
"https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow")
|
||||
ASAN_FLAG(int, detect_odr_violation, 2,
|
||||
"If >=2, detect violation of One-Definition-Rule (ODR); "
|
||||
"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,
|
||||
"If true, dump 16 bytes starting at the instruction that caused SEGV")
|
||||
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!)")
|
||||
|
@ -75,7 +75,7 @@ struct AsanInterceptorContext {
|
||||
} \
|
||||
if (!suppressed) { \
|
||||
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)
|
||||
@ -178,7 +178,7 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
|
||||
} while (false)
|
||||
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
|
||||
// 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) \
|
||||
if (flags()->strict_init_order) { \
|
||||
StopInitOrderChecking(); \
|
||||
|
@ -167,6 +167,19 @@ extern "C" {
|
||||
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_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_load2(uptr p, u32 exp);
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load4(uptr p, u32 exp);
|
||||
|
@ -75,8 +75,6 @@ void AsanCheckIncompatibleRT();
|
||||
|
||||
void AsanOnDeadlySignal(int, void *siginfo, void *context);
|
||||
|
||||
void DisableReexec();
|
||||
void MaybeReexec();
|
||||
void ReadContextStack(void *context, uptr *stack, uptr *ssize);
|
||||
void StopInitOrderChecking();
|
||||
|
||||
|
@ -70,14 +70,6 @@ namespace __asan {
|
||||
|
||||
void InitializePlatformInterceptors() {}
|
||||
|
||||
void DisableReexec() {
|
||||
// No need to re-exec on Linux.
|
||||
}
|
||||
|
||||
void MaybeReexec() {
|
||||
// No need to re-exec on Linux.
|
||||
}
|
||||
|
||||
void *AsanDoesNotSupportStaticLinkage() {
|
||||
// This will fail to link with -static.
|
||||
return &_DYNAMIC; // defined in link.h
|
||||
|
@ -24,15 +24,6 @@
|
||||
#include "sanitizer_common/sanitizer_libc.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 <libkern/OSAtomic.h>
|
||||
#include <mach-o/dyld.h>
|
||||
@ -52,182 +43,12 @@ void InitializePlatformInterceptors() {}
|
||||
bool PlatformHasDifferentMemcpyAndMemmove() {
|
||||
// On OS X 10.7 memcpy() and memmove() are both resolved
|
||||
// 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
|
||||
// actually the same function.
|
||||
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.
|
||||
void *AsanDoesNotSupportStaticLinkage() {
|
||||
return 0;
|
||||
|
@ -26,13 +26,25 @@
|
||||
// ---------------------- Replacement functions ---------------- {{{1
|
||||
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) {
|
||||
GET_STACK_TRACE_FREE;
|
||||
if (UNLIKELY(IsInCallocPool(ptr)))
|
||||
return;
|
||||
asan_free(ptr, &stack, FROM_MALLOC);
|
||||
}
|
||||
|
||||
INTERCEPTOR(void, cfree, void *ptr) {
|
||||
GET_STACK_TRACE_FREE;
|
||||
if (UNLIKELY(IsInCallocPool(ptr)))
|
||||
return;
|
||||
asan_free(ptr, &stack, FROM_MALLOC);
|
||||
}
|
||||
|
||||
@ -44,8 +56,6 @@ INTERCEPTOR(void*, malloc, uptr size) {
|
||||
INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
|
||||
if (UNLIKELY(!asan_inited)) {
|
||||
// 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;
|
||||
uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -54,10 +54,6 @@ using namespace __asan;
|
||||
#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \
|
||||
GET_STACK_TRACE_FREE; \
|
||||
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
|
||||
|
||||
#include "sanitizer_common/sanitizer_malloc_mac.inc"
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "asan_internal.h"
|
||||
|
||||
// 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:
|
||||
// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
|
||||
@ -118,11 +118,7 @@ static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000
|
||||
static const u64 kIosShadowOffset64 = 0x130000000;
|
||||
static const u64 kIosSimShadowOffset32 = 1ULL << 30;
|
||||
static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64;
|
||||
#if SANITIZER_AARCH64_VMA == 39
|
||||
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 kMIPS64_ShadowOffset64 = 1ULL << 37;
|
||||
static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
|
||||
|
@ -30,7 +30,7 @@
|
||||
using namespace __asan; // NOLINT
|
||||
|
||||
// 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>.
|
||||
namespace std {
|
||||
|
@ -102,7 +102,7 @@ using namespace __asan; // NOLINT
|
||||
// that user program (un)poisons the memory it owns. It poisons memory
|
||||
// conservatively, and unpoisons progressively to make sure asan shadow
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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)
|
||||
// CHECK_EQ(*(u8*)MemToShadow(d1), old_mid - d1);
|
||||
if (a + granularity <= d1)
|
||||
|
@ -77,6 +77,8 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
|
||||
ReportStackOverflow(sig);
|
||||
else if (signo == SIGFPE)
|
||||
ReportDeadlySignal("FPE", sig);
|
||||
else if (signo == SIGILL)
|
||||
ReportDeadlySignal("ILL", sig);
|
||||
else
|
||||
ReportDeadlySignal("SEGV", sig);
|
||||
}
|
||||
|
@ -30,7 +30,9 @@ namespace __asan {
|
||||
static void (*error_report_callback)(const char*);
|
||||
static char *error_message_buffer = nullptr;
|
||||
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 {
|
||||
uptr pc;
|
||||
@ -46,16 +48,20 @@ static bool report_happened = false;
|
||||
static ReportData report_data = {};
|
||||
|
||||
void AppendToErrorMessageBuffer(const char *buffer) {
|
||||
if (error_message_buffer) {
|
||||
uptr length = internal_strlen(buffer);
|
||||
CHECK_GE(error_message_buffer_size, error_message_buffer_pos);
|
||||
uptr remaining = error_message_buffer_size - error_message_buffer_pos;
|
||||
internal_strncpy(error_message_buffer + error_message_buffer_pos,
|
||||
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);
|
||||
BlockingMutexLock l(&error_message_buf_mutex);
|
||||
if (!error_message_buffer) {
|
||||
error_message_buffer =
|
||||
(char*)MmapOrDieQuietly(kErrorMessageBufferSize, __func__);
|
||||
error_message_buffer_pos = 0;
|
||||
}
|
||||
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
|
||||
@ -622,26 +628,90 @@ void DescribeThread(AsanThreadContext *context) {
|
||||
// immediately after printing error report.
|
||||
class ScopedInErrorReport {
|
||||
public:
|
||||
explicit ScopedInErrorReport(ReportData *report = nullptr) {
|
||||
static atomic_uint32_t num_calls;
|
||||
static u32 reporting_thread_tid;
|
||||
if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
|
||||
explicit ScopedInErrorReport(ReportData *report = nullptr,
|
||||
bool fatal = false) {
|
||||
halt_on_error_ = fatal || flags()->halt_on_error;
|
||||
|
||||
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.
|
||||
// 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. "
|
||||
"Ignoring.\n");
|
||||
u32 current_tid = GetCurrentTidOrInvalid();
|
||||
if (current_tid != reporting_thread_tid) {
|
||||
// ASan found two bugs in different threads simultaneously. Sleep
|
||||
// long enough to make sure that the thread which started to print
|
||||
// an error report will finish doing it.
|
||||
SleepForSeconds(Max(100, flags()->sleep_before_dying + 1));
|
||||
}
|
||||
"Ignoring.\n");
|
||||
|
||||
// Sleep long enough to make sure that the thread which started
|
||||
// to print 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
|
||||
// Die() to bypass any additional checks.
|
||||
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;
|
||||
report_happened = true;
|
||||
ASAN_ON_ERROR();
|
||||
@ -651,27 +721,19 @@ class ScopedInErrorReport {
|
||||
// recursive reports.
|
||||
asanThreadRegistry().Lock();
|
||||
CommonSanitizerReportMutex.Lock();
|
||||
reporting_thread_tid = GetCurrentTidOrInvalid();
|
||||
reporting_thread_tid_ = GetCurrentTidOrInvalid();
|
||||
Printf("===================================================="
|
||||
"=============\n");
|
||||
}
|
||||
// Destructor is NORETURN, as functions that report errors are.
|
||||
NORETURN ~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();
|
||||
if (error_report_callback) {
|
||||
error_report_callback(error_message_buffer);
|
||||
}
|
||||
Report("ABORTING\n");
|
||||
Die();
|
||||
}
|
||||
|
||||
static StaticSpinMutex lock_;
|
||||
static u32 reporting_thread_tid_;
|
||||
bool halt_on_error_;
|
||||
};
|
||||
|
||||
StaticSpinMutex ScopedInErrorReport::lock_;
|
||||
u32 ScopedInErrorReport::reporting_thread_tid_;
|
||||
|
||||
void ReportStackOverflow(const SignalContext &sig) {
|
||||
ScopedInErrorReport in_report;
|
||||
Decorator d;
|
||||
@ -688,7 +750,7 @@ void ReportStackOverflow(const SignalContext &sig) {
|
||||
}
|
||||
|
||||
void ReportDeadlySignal(const char *description, const SignalContext &sig) {
|
||||
ScopedInErrorReport in_report;
|
||||
ScopedInErrorReport in_report(/*report*/nullptr, /*fatal*/true);
|
||||
Decorator d;
|
||||
Printf("%s", d.Warning());
|
||||
Report(
|
||||
@ -745,7 +807,7 @@ void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
|
||||
stack.Print();
|
||||
DescribeHeapAddress(addr, 1);
|
||||
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");
|
||||
}
|
||||
|
||||
@ -785,7 +847,7 @@ void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
|
||||
stack.Print();
|
||||
DescribeHeapAddress(addr, 1);
|
||||
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");
|
||||
}
|
||||
|
||||
@ -887,7 +949,7 @@ void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
|
||||
Printf(" [2]:\n");
|
||||
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");
|
||||
InternalScopedString error_msg(256);
|
||||
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
|
||||
|
||||
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,
|
||||
BufferedStackTrace *stack) {
|
||||
ScopedInErrorReport in_report;
|
||||
@ -948,24 +999,23 @@ void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
|
||||
DescribeHeapAddress(addr, 1);
|
||||
}
|
||||
|
||||
void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
|
||||
BufferedStackTrace *stack) {
|
||||
ScopedInErrorReport in_report;
|
||||
Printf("cf_realloc(%p) -- attempting to realloc unallocated memory.\n"
|
||||
"This is an unrecoverable problem, exiting now.\n",
|
||||
addr);
|
||||
PrintZoneForPointer(addr, zone_ptr, zone_name);
|
||||
stack->Print();
|
||||
DescribeHeapAddress(addr, 1);
|
||||
// -------------- SuppressErrorReport -------------- {{{1
|
||||
// Avoid error reports duplicating for ASan recover mode.
|
||||
static bool SuppressErrorReport(uptr pc) {
|
||||
if (!common_flags()->suppress_equal_pcs) return false;
|
||||
for (unsigned i = 0; i < kAsanBuggyPcPoolSize; i++) {
|
||||
uptr cmp = atomic_load_relaxed(&AsanBuggyPcPool[i]);
|
||||
if (cmp == 0 && atomic_compare_exchange_strong(&AsanBuggyPcPool[i], &cmp,
|
||||
pc, memory_order_relaxed))
|
||||
return false;
|
||||
if (cmp == pc) return true;
|
||||
}
|
||||
Die();
|
||||
}
|
||||
|
||||
} // 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) {
|
||||
void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
|
||||
uptr access_size, u32 exp, bool fatal) {
|
||||
if (!fatal && SuppressErrorReport(pc)) return;
|
||||
ENABLE_FRAME_POINTER;
|
||||
|
||||
// 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,
|
||||
bug_descr };
|
||||
ScopedInErrorReport in_report(&report);
|
||||
ScopedInErrorReport in_report(&report, fatal);
|
||||
|
||||
Decorator d;
|
||||
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);
|
||||
}
|
||||
|
||||
} // 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*)) {
|
||||
BlockingMutexLock l(&error_message_buf_mutex);
|
||||
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) {
|
||||
|
@ -49,45 +49,39 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size);
|
||||
void DescribeThread(AsanThreadContext *context);
|
||||
|
||||
// Different kinds of error reports.
|
||||
void NORETURN ReportStackOverflow(const SignalContext &sig);
|
||||
void NORETURN ReportDeadlySignal(const char* description,
|
||||
const SignalContext &sig);
|
||||
void NORETURN ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
|
||||
BufferedStackTrace *free_stack);
|
||||
void NORETURN ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
|
||||
void NORETURN ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);
|
||||
void NORETURN ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
|
||||
AllocType alloc_type,
|
||||
AllocType dealloc_type);
|
||||
void NORETURN
|
||||
ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
|
||||
void NORETURN
|
||||
ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
|
||||
BufferedStackTrace *stack);
|
||||
void NORETURN
|
||||
ReportStringFunctionMemoryRangesOverlap(const char *function,
|
||||
const char *offset1, uptr length1,
|
||||
const char *offset2, uptr length2,
|
||||
BufferedStackTrace *stack);
|
||||
void NORETURN ReportStringFunctionSizeOverflow(uptr offset, uptr size,
|
||||
BufferedStackTrace *stack);
|
||||
void NORETURN
|
||||
ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
|
||||
uptr old_mid, uptr new_mid,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
|
||||
uptr access_size, u32 exp, bool fatal);
|
||||
void ReportStackOverflow(const SignalContext &sig);
|
||||
void ReportDeadlySignal(const char *description, const SignalContext &sig);
|
||||
void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size,
|
||||
BufferedStackTrace *free_stack);
|
||||
void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
|
||||
void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);
|
||||
void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
|
||||
AllocType alloc_type,
|
||||
AllocType dealloc_type);
|
||||
void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
|
||||
void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportStringFunctionMemoryRangesOverlap(const char *function,
|
||||
const char *offset1, uptr length1,
|
||||
const char *offset2, uptr length2,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
|
||||
uptr old_mid, uptr new_mid,
|
||||
BufferedStackTrace *stack);
|
||||
|
||||
void NORETURN
|
||||
ReportODRViolation(const __asan_global *g1, u32 stack_id1,
|
||||
const __asan_global *g2, u32 stack_id2);
|
||||
void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
|
||||
const __asan_global *g2, u32 stack_id2);
|
||||
|
||||
// Mac-specific errors and warnings.
|
||||
void WarnMacFreeUnallocated(uptr addr, uptr zone_ptr, const char *zone_name,
|
||||
BufferedStackTrace *stack);
|
||||
void NORETURN ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,
|
||||
const char *zone_name,
|
||||
BufferedStackTrace *stack);
|
||||
void NORETURN ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,
|
||||
const char *zone_name,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,
|
||||
const char *zone_name,
|
||||
BufferedStackTrace *stack);
|
||||
void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,
|
||||
const char *zone_name,
|
||||
BufferedStackTrace *stack);
|
||||
|
||||
} // namespace __asan
|
||||
|
@ -113,13 +113,18 @@ static void OnLowLevelAllocate(uptr ptr, uptr size) {
|
||||
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
||||
void __asan_report_ ## type ## size(uptr addr) { \
|
||||
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 \
|
||||
void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \
|
||||
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, 2)
|
||||
@ -132,22 +137,27 @@ ASAN_REPORT_ERROR(store, true, 4)
|
||||
ASAN_REPORT_ERROR(store, true, 8)
|
||||
ASAN_REPORT_ERROR(store, true, 16)
|
||||
|
||||
#define ASAN_REPORT_ERROR_N(type, is_write) \
|
||||
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
||||
void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
|
||||
GET_CALLER_PC_BP_SP; \
|
||||
__asan_report_error(pc, bp, sp, addr, is_write, size, 0); \
|
||||
} \
|
||||
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
||||
#define ASAN_REPORT_ERROR_N(type, is_write) \
|
||||
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
||||
void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
|
||||
GET_CALLER_PC_BP_SP; \
|
||||
ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
|
||||
} \
|
||||
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
||||
void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \
|
||||
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(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 s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
|
||||
: *reinterpret_cast<u16 *>(sp); \
|
||||
@ -159,7 +169,8 @@ ASAN_REPORT_ERROR_N(store, true)
|
||||
*__asan_test_only_reported_buggy_pointer = addr; \
|
||||
} else { \
|
||||
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) \
|
||||
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
||||
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 \
|
||||
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, 2)
|
||||
@ -190,7 +205,7 @@ NOINLINE INTERFACE_ATTRIBUTE
|
||||
void __asan_loadN(uptr addr, uptr size) {
|
||||
if (__asan_region_is_poisoned(addr, size)) {
|
||||
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) {
|
||||
if (__asan_region_is_poisoned(addr, size)) {
|
||||
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) {
|
||||
if (__asan_region_is_poisoned(addr, size)) {
|
||||
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) {
|
||||
if (__asan_region_is_poisoned(addr, size)) {
|
||||
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) {
|
||||
if (!flags()->protect_shadow_gap)
|
||||
return;
|
||||
void *res = MmapNoAccess(addr, size, "shadow gap");
|
||||
if (addr == (uptr)res)
|
||||
return;
|
||||
@ -378,8 +413,6 @@ static void AsanInitInternal() {
|
||||
// initialization steps look at flags().
|
||||
InitializeFlags();
|
||||
|
||||
CheckVMASize();
|
||||
|
||||
AsanCheckIncompatibleRT();
|
||||
AsanCheckDynamicRTPrereqs();
|
||||
|
||||
@ -572,7 +605,7 @@ void NOINLINE __asan_handle_no_return() {
|
||||
"stack top: %p; bottom %p; size: %p (%zd)\n"
|
||||
"False positive error reports may follow\n"
|
||||
"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);
|
||||
return;
|
||||
}
|
||||
|
@ -175,14 +175,6 @@ void PlatformTSDDtor(void *tsd) {
|
||||
// }}}
|
||||
|
||||
// ---------------------- Various stuff ---------------- {{{
|
||||
void DisableReexec() {
|
||||
// No need to re-exec on Windows.
|
||||
}
|
||||
|
||||
void MaybeReexec() {
|
||||
// No need to re-exec on Windows.
|
||||
}
|
||||
|
||||
void *AsanDoesNotSupportStaticLinkage() {
|
||||
#if defined(_DEBUG)
|
||||
#error Please build the runtime with a non-debug CRT: /MD or /MT
|
||||
|
@ -12,8 +12,7 @@
|
||||
// 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
|
||||
// shared runtime that lives in the main binary.
|
||||
// See https://code.google.com/p/address-sanitizer/issues/detail?id=209 for the
|
||||
// details.
|
||||
// See https://github.com/google/sanitizers/issues/209 for the details.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// 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_memmove);
|
||||
|
||||
INTERFACE_FUNCTION(__asan_alloca_poison);
|
||||
INTERFACE_FUNCTION(__asan_allocas_unpoison);
|
||||
|
||||
INTERFACE_FUNCTION(__asan_register_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?
|
||||
INTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container)
|
||||
INTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address)
|
||||
INTERFACE_FUNCTION(__sanitizer_cov)
|
||||
INTERFACE_FUNCTION(__sanitizer_cov_dump)
|
||||
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_get_allocated_size)
|
||||
INTERFACE_FUNCTION(__sanitizer_get_coverage_guards)
|
||||
INTERFACE_FUNCTION(__sanitizer_get_coverage_pc_buffer)
|
||||
INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes)
|
||||
INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size)
|
||||
INTERFACE_FUNCTION(__sanitizer_get_free_bytes)
|
||||
INTERFACE_FUNCTION(__sanitizer_get_heap_size)
|
||||
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_unmapped_bytes)
|
||||
INTERFACE_FUNCTION(__sanitizer_maybe_open_cov_file)
|
||||
|
@ -59,6 +59,7 @@ int __asan_option_detect_stack_use_after_return =
|
||||
// using atexit() that calls a small subset of C terminators
|
||||
// where LLVM global_dtors is placed. Fingers crossed, no other C terminators
|
||||
// are there.
|
||||
extern "C" int __cdecl atexit(void (__cdecl *f)(void));
|
||||
extern "C" void __cdecl _initterm(void *a, void *b);
|
||||
|
||||
namespace {
|
||||
|
@ -222,8 +222,13 @@ elif [[ -f "$HERE/$ASAN_RT" ]]; then
|
||||
ASAN_RT_PATH="$HERE"
|
||||
elif [[ $(basename "$HERE") == "bin" ]]; then
|
||||
# We could be in the toolchain's base directory.
|
||||
# Consider ../lib, ../lib/asan, ../lib/linux and ../lib/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" 2>/dev/null | sort | tail -1)
|
||||
# Consider ../lib, ../lib/asan, ../lib/linux,
|
||||
# ../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
|
||||
ASAN_RT_PATH="$(dirname "$P")"
|
||||
fi
|
||||
|
@ -271,7 +271,7 @@ def BreakpadSymbolizerFactory(binary):
|
||||
def SystemSymbolizerFactory(system, addr, binary):
|
||||
if system == 'Darwin':
|
||||
return DarwinSymbolizer(addr, binary)
|
||||
elif system == 'Linux':
|
||||
elif system == 'Linux' or system == 'FreeBSD':
|
||||
return Addr2LineSymbolizer(binary)
|
||||
|
||||
|
||||
|
@ -216,12 +216,12 @@ TEST(AddressSanitizerMac, NSObjectOOB) {
|
||||
|
||||
// Make sure that correct pointer is passed to free() when deallocating a
|
||||
// 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) {
|
||||
TestNSURLDeallocation();
|
||||
}
|
||||
|
||||
// See http://code.google.com/p/address-sanitizer/issues/detail?id=109.
|
||||
// See https://github.com/google/sanitizers/issues/109.
|
||||
TEST(AddressSanitizerMac, Mstats) {
|
||||
malloc_statistics_t stats1, stats2;
|
||||
malloc_zone_statistics(/*all zones*/NULL, &stats1);
|
||||
|
@ -34,7 +34,7 @@
|
||||
// Make sure __asan_init is called before any test case is run.
|
||||
struct AsanInitCaller {
|
||||
AsanInitCaller() {
|
||||
__asan::DisableReexec();
|
||||
DisableReexec();
|
||||
__asan_init();
|
||||
}
|
||||
};
|
||||
|
@ -610,7 +610,7 @@ NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
static jmp_buf buf;
|
||||
if (!__builtin_setjmp((void**)buf)) {
|
||||
@ -1156,9 +1156,9 @@ TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {
|
||||
// The new/delete/etc mismatch checks don't work on Android,
|
||||
// as calls to new/delete go through malloc/free.
|
||||
// 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:
|
||||
// https://code.google.com/p/address-sanitizer/issues/detail?id=309
|
||||
// https://github.com/google/sanitizers/issues/309
|
||||
#if !defined(__ANDROID__) && \
|
||||
!defined(__APPLE__) && \
|
||||
!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) {
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
delete [] (Ident(new char [8644]));
|
||||
|
@ -19,7 +19,8 @@ extern "C" const char* __asan_default_options() {
|
||||
#if SANITIZER_MAC
|
||||
// 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'.
|
||||
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
|
||||
return "symbolize=false";
|
||||
#endif
|
||||
|
@ -2,6 +2,9 @@
|
||||
# generic implementations of the core runtime library along with optimized
|
||||
# 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
|
||||
absvdi2.c
|
||||
absvsi2.c
|
||||
@ -150,7 +153,7 @@ if(APPLE)
|
||||
atomic_thread_fence.c)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
if(NOT WIN32 OR MINGW)
|
||||
set(GENERIC_SOURCES
|
||||
${GENERIC_SOURCES}
|
||||
emutls.c)
|
||||
@ -164,6 +167,8 @@ endif ()
|
||||
|
||||
if (NOT MSVC)
|
||||
set(x86_64_SOURCES
|
||||
x86_64/chkstk.S
|
||||
x86_64/chkstk2.S
|
||||
x86_64/floatdidf.c
|
||||
x86_64/floatdisf.c
|
||||
x86_64/floatdixf.c
|
||||
@ -183,6 +188,8 @@ if (NOT MSVC)
|
||||
set(i386_SOURCES
|
||||
i386/ashldi3.S
|
||||
i386/ashrdi3.S
|
||||
i386/chkstk.S
|
||||
i386/chkstk2.S
|
||||
i386/divdi3.S
|
||||
i386/floatdidf.S
|
||||
i386/floatdisf.S
|
||||
@ -219,7 +226,8 @@ else () # MSVC
|
||||
set(i686_SOURCES ${i386_SOURCES})
|
||||
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_cdcmpeq_check_nan.c
|
||||
arm/aeabi_cfcmp.S
|
||||
@ -239,36 +247,16 @@ set(arm_SOURCES
|
||||
arm/aeabi_uldivmod.S
|
||||
arm/bswapdi2.S
|
||||
arm/bswapsi2.S
|
||||
arm/clzdi2.S
|
||||
arm/clzsi2.S
|
||||
arm/comparesf2.S
|
||||
arm/divmodsi4.S
|
||||
arm/divsi3.S
|
||||
arm/modsi3.S
|
||||
arm/negdf2vfp.S
|
||||
arm/negsf2vfp.S
|
||||
arm/switch16.S
|
||||
arm/switch32.S
|
||||
arm/switch8.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/udivmodsi4.S
|
||||
arm/udivsi3.S
|
||||
@ -294,7 +282,32 @@ set(aarch64_SOURCES
|
||||
trunctfsf2.c
|
||||
${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/addsf3vfp.S
|
||||
arm/divdf3vfp.S
|
||||
@ -320,6 +333,8 @@ set(armhf_SOURCES
|
||||
arm/ltsf2vfp.S
|
||||
arm/muldf3vfp.S
|
||||
arm/mulsf3vfp.S
|
||||
arm/negdf2vfp.S
|
||||
arm/negsf2vfp.S
|
||||
arm/nedf2vfp.S
|
||||
arm/nesf2vfp.S
|
||||
arm/restore_vfp_d8_d15_regs.S
|
||||
@ -328,22 +343,31 @@ set(armhf_SOURCES
|
||||
arm/subsf3vfp.S
|
||||
arm/truncdfsf2vfp.S
|
||||
arm/unorddf2vfp.S
|
||||
arm/unordsf2vfp.S
|
||||
${arm_SOURCES})
|
||||
set(armv7_SOURCES ${arm_SOURCES})
|
||||
set(armv7s_SOURCES ${arm_SOURCES})
|
||||
arm/unordsf2vfp.S)
|
||||
|
||||
set(arm_SOURCES ${arm_GENERIC_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})
|
||||
|
||||
# macho_embedded archs
|
||||
set(armv6m_SOURCES ${GENERIC_SOURCES})
|
||||
set(armv7m_SOURCES ${arm_SOURCES})
|
||||
set(armv7em_SOURCES ${arm_SOURCES})
|
||||
set(armv7m_SOURCES ${arm_GENERIC_SOURCES} ${arm_THUMB_SOURCES})
|
||||
set(armv7em_SOURCES ${arm_GENERIC_SOURCES} ${arm_THUMB_SOURCES})
|
||||
|
||||
set(mips_SOURCES ${GENERIC_SOURCES})
|
||||
set(mipsel_SOURCES ${mips_SOURCES})
|
||||
set(mips64_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)
|
||||
|
||||
if (APPLE)
|
||||
@ -351,6 +375,8 @@ if (APPLE)
|
||||
add_subdirectory(macho_embedded)
|
||||
darwin_add_builtin_libraries(${BUILTIN_SUPPORTED_OS})
|
||||
else ()
|
||||
append_string_if(COMPILER_RT_HAS_STD_C99_FLAG -std=c99 maybe_stdc99)
|
||||
|
||||
foreach (arch ${BUILTIN_SUPPORTED_ARCH})
|
||||
if (CAN_TARGET_${arch})
|
||||
# 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
|
||||
if (MSVC)
|
||||
set(_cflags -Zl)
|
||||
else ()
|
||||
set(_cflags -std=c99)
|
||||
set(maybe_zl -Zl)
|
||||
endif ()
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.builtins
|
||||
STATIC
|
||||
ARCHS ${arch}
|
||||
SOURCES ${${arch}_SOURCES}
|
||||
CFLAGS ${_cflags}
|
||||
CFLAGS ${maybe_stdc99} ${maybe_zl}
|
||||
PARENT_TARGET builtins)
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
@ -1,3 +1,6 @@
|
||||
absvti2
|
||||
addtf3
|
||||
addvti3
|
||||
aeabi_cdcmp
|
||||
aeabi_cdcmpeq_check_nan
|
||||
aeabi_cfcmp
|
||||
@ -15,16 +18,13 @@ aeabi_memmove
|
||||
aeabi_memset
|
||||
aeabi_uidivmod
|
||||
aeabi_uldivmod
|
||||
absvti2
|
||||
addtf3
|
||||
addvti3
|
||||
ashlti3
|
||||
ashrti3
|
||||
clzti2
|
||||
cmpti2
|
||||
ctzti2
|
||||
divti3
|
||||
divtf3
|
||||
divti3
|
||||
ffsti2
|
||||
fixdfti
|
||||
fixsfti
|
||||
@ -40,58 +40,16 @@ floatuntisf
|
||||
floatuntixf
|
||||
lshrti3
|
||||
modti3
|
||||
muloti4
|
||||
multi3
|
||||
multf3
|
||||
multi3
|
||||
mulvti3
|
||||
negti2
|
||||
negvti2
|
||||
parityti2
|
||||
popcountti2
|
||||
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
|
||||
subvti3
|
||||
trampoline_setup
|
||||
ucmpti2
|
||||
udivmodti4
|
||||
|
@ -1,3 +1,6 @@
|
||||
absvti2
|
||||
addtf3
|
||||
addvti3
|
||||
aeabi_cdcmp
|
||||
aeabi_cdcmpeq_check_nan
|
||||
aeabi_cfcmp
|
||||
@ -15,16 +18,13 @@ aeabi_memmove
|
||||
aeabi_memset
|
||||
aeabi_uidivmod
|
||||
aeabi_uldivmod
|
||||
absvti2
|
||||
addtf3
|
||||
addvti3
|
||||
ashlti3
|
||||
ashrti3
|
||||
clzti2
|
||||
cmpti2
|
||||
ctzti2
|
||||
divti3
|
||||
divtf3
|
||||
divti3
|
||||
ffsti2
|
||||
fixdfti
|
||||
fixsfti
|
||||
@ -40,58 +40,16 @@ floatuntisf
|
||||
floatuntixf
|
||||
lshrti3
|
||||
modti3
|
||||
muloti4
|
||||
multf
|
||||
multi3
|
||||
multf3
|
||||
mulvti3
|
||||
negti2
|
||||
negvti2
|
||||
parityti2
|
||||
popcountti2
|
||||
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
|
||||
subvti3
|
||||
trampoline_setup
|
||||
ucmpti2
|
||||
udivmodti4
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__adddf3vfp)
|
||||
vmov r0, r1, d6 // move result back to r0/r1 pair
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__adddf3vfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__addsf3vfp)
|
||||
vmov r0, s14 // move result back to r0
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__addsf3vfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -94,3 +94,5 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
|
||||
b __aeabi_cdcmple
|
||||
END_COMPILERRT_FUNCTION(__aeabi_cdrcmple)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -89,3 +89,5 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
|
||||
b __aeabi_cfcmple
|
||||
END_COMPILERRT_FUNCTION(__aeabi_cfrcmple)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -38,3 +38,6 @@ DEFINE_AEABI_DCMP(lt)
|
||||
DEFINE_AEABI_DCMP(le)
|
||||
DEFINE_AEABI_DCMP(ge)
|
||||
DEFINE_AEABI_DCMP(gt)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -38,3 +38,6 @@ DEFINE_AEABI_FCMP(lt)
|
||||
DEFINE_AEABI_FCMP(le)
|
||||
DEFINE_AEABI_FCMP(ge)
|
||||
DEFINE_AEABI_FCMP(gt)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -26,3 +26,6 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_idivmod)
|
||||
add sp, sp, #4
|
||||
pop { pc }
|
||||
END_COMPILERRT_FUNCTION(__aeabi_idivmod)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -29,3 +29,6 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
|
||||
add sp, sp, #16
|
||||
pop {r11, pc}
|
||||
END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -18,3 +18,6 @@ END_COMPILERRT_FUNCTION(__aeabi_memcmp)
|
||||
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp4, __aeabi_memcmp)
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcmp8, __aeabi_memcmp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -18,3 +18,6 @@ END_COMPILERRT_FUNCTION(__aeabi_memcpy)
|
||||
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy4, __aeabi_memcpy)
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memcpy8, __aeabi_memcpy)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -18,3 +18,6 @@ END_COMPILERRT_FUNCTION(__aeabi_memmove)
|
||||
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove4, __aeabi_memmove)
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memmove8, __aeabi_memmove)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -32,3 +32,5 @@ END_COMPILERRT_FUNCTION(__aeabi_memclr)
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr4, __aeabi_memclr)
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_memclr8, __aeabi_memclr)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -27,3 +27,6 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod)
|
||||
add sp, sp, #4
|
||||
pop { pc }
|
||||
END_COMPILERRT_FUNCTION(__aeabi_uidivmod)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -29,3 +29,6 @@ DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod)
|
||||
add sp, sp, #16
|
||||
pop {r11, pc}
|
||||
END_COMPILERRT_FUNCTION(__aeabi_uldivmod)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -45,3 +45,6 @@ DEFINE_COMPILERRT_FUNCTION(__bswapdi2)
|
||||
mov r1, r2 // r1 = r2 = rev(r0)
|
||||
JMP(lr)
|
||||
END_COMPILERRT_FUNCTION(__bswapdi2)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -37,3 +37,6 @@ DEFINE_COMPILERRT_FUNCTION(__bswapsi2)
|
||||
#endif
|
||||
JMP(lr)
|
||||
END_COMPILERRT_FUNCTION(__bswapsi2)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -95,3 +95,6 @@ DEFINE_COMPILERRT_FUNCTION(__clzdi2)
|
||||
JMP(lr)
|
||||
#endif // __ARM_FEATURE_CLZ
|
||||
END_COMPILERRT_FUNCTION(__clzdi2)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -74,3 +74,6 @@ DEFINE_COMPILERRT_FUNCTION(__clzsi2)
|
||||
JMP(lr)
|
||||
#endif // __ARM_FEATURE_CLZ
|
||||
END_COMPILERRT_FUNCTION(__clzsi2)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -146,3 +146,6 @@ DEFINE_COMPILERRT_FUNCTION(__unordsf2)
|
||||
END_COMPILERRT_FUNCTION(__unordsf2)
|
||||
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_fcmpun, __unordsf2)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__divdf3vfp)
|
||||
vmov r0, r1, d5 // move result back to r0/r1 pair
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__divdf3vfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -72,3 +72,6 @@ LOCAL_LABEL(divzero):
|
||||
CLEAR_FRAME_AND_RETURN
|
||||
#endif
|
||||
END_COMPILERRT_FUNCTION(__divmodsi4)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__divsf3vfp)
|
||||
vmov r0, s13 // move result back to r0
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__divsf3vfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -63,3 +63,6 @@ ESTABLISH_FRAME
|
||||
CLEAR_FRAME_AND_RETURN
|
||||
#endif
|
||||
END_COMPILERRT_FUNCTION(__divsi3)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -27,3 +27,6 @@ DEFINE_COMPILERRT_FUNCTION(__eqdf2vfp)
|
||||
movne r0, #0
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__eqdf2vfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -27,3 +27,6 @@ DEFINE_COMPILERRT_FUNCTION(__eqsf2vfp)
|
||||
movne r0, #0
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__eqsf2vfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__extendsfdf2vfp)
|
||||
vmov r0, r1, d7 // return result in r0/r1 pair
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__extendsfdf2vfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__fixdfsivfp)
|
||||
vmov r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__fixdfsivfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__fixsfsivfp)
|
||||
vmov r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__fixsfsivfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -25,3 +25,6 @@ DEFINE_COMPILERRT_FUNCTION(__fixunsdfsivfp)
|
||||
vmov r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__fixunsdfsivfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -25,3 +25,6 @@ DEFINE_COMPILERRT_FUNCTION(__fixunssfsivfp)
|
||||
vmov r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__fixunssfsivfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__floatsidfvfp)
|
||||
vmov r0, r1, d7 // move d7 to result register pair r0/r1
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__floatsidfvfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__floatsisfvfp)
|
||||
vmov r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__floatsisfvfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__floatunssidfvfp)
|
||||
vmov r0, r1, d7 // move d7 to result register pair r0/r1
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__floatunssidfvfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -24,3 +24,6 @@ DEFINE_COMPILERRT_FUNCTION(__floatunssisfvfp)
|
||||
vmov r0, s15 // move s15 to result register
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__floatunssisfvfp)
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user