3 # Run as: CLANG=bin/clang ZLIB_SRC=src/zlib \
4 # build_symbolizer.sh runtime_build/lib/clang/4.0.0/lib/linux/
5 # zlib can be downloaded from http://www.zlib.net.
7 # Script compiles self-contained object file with symbolization code and injects
8 # it into the given set of runtime libraries. Script updates only libraries
9 # which has unresolved __sanitizer_symbolize_* symbols and matches architecture.
10 # Object file is be compiled from LLVM sources with dependencies like libc++ and
11 # zlib. Then it internalizes symbols in the file, so that it can be linked
12 # into arbitrary programs, avoiding conflicts with the program own symbols and
13 # avoiding dependencies on any program symbols. The only acceptable dependencies
14 # are libc and __sanitizer::internal_* from sanitizer runtime.
16 # Symbols exported by the object file will be used by Sanitizer runtime
17 # libraries to symbolize code/data in-process.
19 # The script will modify the output directory which is given as the first
20 # argument to the script.
22 # FIXME: We should really be using a simpler approach to building this object
23 # file, and it should be available as a regular cmake rule. Conceptually, we
24 # want to be doing "ld -r" followed by "objcopy -G" to create a relocatable
25 # object file with only our entry points exposed. However, this does not work at
26 # present, see PR30750.
32 SCRIPT_DIR
=$
(cd "$(dirname "$0")" && pwd)
33 SRC_DIR
=$
(readlink
-f $SCRIPT_DIR/..
)
34 TARGE_DIR
=$
(readlink
-f $1)
35 COMPILER_RT_SRC
=$
(readlink
-f ${SCRIPT_DIR}/..
/..
/..
/..
)
36 LLVM_SRC
=${LLVM_SRC:-${COMPILER_RT_SRC}/../llvm}
37 LLVM_SRC
=$
(readlink
-f $LLVM_SRC)
38 if [[ ! -d "${LLVM_SRC}/../llvm" ]] ; then
39 LLVM_SRC
=$
(readlink
-f ${COMPILER_RT_SRC}/..
/..
/..
/llvm
)
41 LIBCXX_SRC
=$
(readlink
-f ${COMPILER_RT_SRC}/..
/libcxx
)
42 LIBCXXABI_SRC
=$
(readlink
-f ${COMPILER_RT_SRC}/..
/libcxxabi
)
44 if [[ ! -d "${LLVM_SRC}/../llvm" ||
45 ! -d "${LIBCXX_SRC}" ||
46 ! -d "${LIBCXXABI_SRC}" ]]; then
47 echo "Missing or incomplete LLVM_SRC"
51 if [[ "$ZLIB_SRC" == "" ||
52 ! -x "${ZLIB_SRC}/configure" ||
53 ! -f "${ZLIB_SRC}/zlib.h" ]]; then
54 echo "Missing or incomplete ZLIB_SRC"
57 ZLIB_SRC
=$
(readlink
-f $ZLIB_SRC)
61 CLANG
="${CLANG:-`which clang`}"
62 CLANG_DIR
=$
(readlink
-f $
(dirname "$CLANG"))
64 BUILD_DIR
=$
(readlink
-f .
/symbolizer
)
69 CXX
=$CLANG_DIR/clang
++
70 TBLGEN
=$CLANG_DIR/llvm-tblgen
72 export AR
=$CLANG_DIR/llvm-ar
73 export LINK
=$CLANG_DIR/llvm-link
74 TARGET_TRIPLE
=$
($CC -print-target-triple)
76 for F
in $CC $CXX $TBLGEN $LINK $OPT $AR; do
77 if [[ ! -x "$F" ]]; then
83 ZLIB_BUILD
=${BUILD_DIR}/zlib
84 LIBCXX_BUILD
=${BUILD_DIR}/libcxx
85 LLVM_BUILD
=${BUILD_DIR}/llvm
86 SYMBOLIZER_BUILD
=${BUILD_DIR}/symbolizer
89 FLAGS
="$FLAGS -fPIC -flto -Os -g0 -DNDEBUG"
92 mkdir
-p ${ZLIB_BUILD}
95 CC
=$CC CFLAGS
="$FLAGS" RANLIB
=/bin
/true .
/configure
--static
98 # Build and install libcxxabi and libcxx.
99 if [[ ! -d ${LIBCXX_BUILD} ]]; then
100 mkdir
-p ${LIBCXX_BUILD}
102 LIBCXX_FLAGS
="${FLAGS} -Wno-macro-redefined"
104 if [[ ! -d $LLVM_SRC/projects
/libcxxabi
]] ; then
105 PROJECTS
="-DLLVM_ENABLE_PROJECTS='libcxx;libcxxabi'"
109 -DCMAKE_BUILD_TYPE=Release \
110 -DCMAKE_C_COMPILER=$CC \
111 -DCMAKE_CXX_COMPILER=$CXX \
112 -DCMAKE_C_FLAGS_RELEASE="${LIBCXX_FLAGS}" \
113 -DCMAKE_CXX_FLAGS_RELEASE="${LIBCXX_FLAGS}" \
114 -DLIBCXXABI_ENABLE_ASSERTIONS=OFF \
115 -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF \
116 -DLIBCXXABI_ENABLE_SHARED=OFF \
117 -DLIBCXX_ENABLE_ASSERTIONS=OFF \
118 -DLIBCXX_ENABLE_EXCEPTIONS=OFF \
119 -DLIBCXX_ENABLE_RTTI=OFF \
120 -DLIBCXX_ENABLE_SHARED=OFF \
126 FLAGS
="${FLAGS} -fno-rtti -fno-exceptions"
127 LLVM_FLAGS
="${FLAGS} -nostdinc++ -I${ZLIB_BUILD} -isystem ${LIBCXX_BUILD}/include/${TARGET_TRIPLE}/c++/v1 -isystem ${LIBCXX_BUILD}/include/c++/v1 -Wno-error=global-constructors"
130 if [[ ! -d ${LLVM_BUILD} ]]; then
131 mkdir
-p ${LLVM_BUILD}
134 -DCMAKE_BUILD_TYPE=Release \
135 -DCMAKE_C_COMPILER=$CC \
136 -DCMAKE_CXX_COMPILER=$CXX \
137 -DCMAKE_C_FLAGS_RELEASE="${LLVM_FLAGS}" \
138 -DCMAKE_CXX_FLAGS_RELEASE="${LLVM_FLAGS}" \
139 -DLLVM_TABLEGEN=$TBLGEN \
140 -DLLVM_ENABLE_ZLIB=ON \
141 -DLLVM_ENABLE_TERMINFO=OFF \
142 -DLLVM_ENABLE_THREADS=OFF \
143 -DLLVM_DISABLE_ASSEMBLY_FILES=ON \
147 ninja LLVMSymbolize LLVMObject LLVMBinaryFormat LLVMDebugInfoDWARF LLVMSupport LLVMDebugInfoPDB LLVMDebuginfod LLVMMC LLVMDemangle LLVMTextAPI
150 rm -rf ${SYMBOLIZER_BUILD}
151 mkdir
${SYMBOLIZER_BUILD}
152 cd ${SYMBOLIZER_BUILD}
155 SYMBOLIZER_FLAGS
="$LLVM_FLAGS -I${LLVM_SRC}/include -I${LLVM_BUILD}/include -std=c++14"
156 $CXX $SYMBOLIZER_FLAGS ${SRC_DIR}/sanitizer_symbolize.cpp
${SRC_DIR}/sanitizer_wrappers.cpp
-c
157 $AR rc symbolizer.a sanitizer_symbolize.o sanitizer_wrappers.o
159 SYMBOLIZER_API_LIST
=__sanitizer_symbolize_code
160 SYMBOLIZER_API_LIST
+=,__sanitizer_symbolize_data
161 SYMBOLIZER_API_LIST
+=,__sanitizer_symbolize_flush
162 SYMBOLIZER_API_LIST
+=,__sanitizer_symbolize_demangle
163 SYMBOLIZER_API_LIST
+=,__sanitizer_symbolize_set_demangle
164 SYMBOLIZER_API_LIST
+=,__sanitizer_symbolize_set_inline_frames
166 LIBCXX_ARCHIVE_DIR
=$
(dirname $
(find $LIBCXX_BUILD -name libc
++.a |
head -n1))
168 # Merge all the object files together and copy the resulting library back.
169 $SCRIPT_DIR/ar_to_bc.sh
$LIBCXX_ARCHIVE_DIR/libc
++.a \
170 $LIBCXX_ARCHIVE_DIR/libc
++abi.a \
171 $LLVM_BUILD/lib
/libLLVMSymbolize.a \
172 $LLVM_BUILD/lib
/libLLVMObject.a \
173 $LLVM_BUILD/lib
/libLLVMBinaryFormat.a \
174 $LLVM_BUILD/lib
/libLLVMDebugInfoDWARF.a \
175 $LLVM_BUILD/lib
/libLLVMSupport.a \
176 $LLVM_BUILD/lib
/libLLVMDebugInfoPDB.a \
177 $LLVM_BUILD/lib
/libLLVMDebugInfoMSF.a \
178 $LLVM_BUILD/lib
/libLLVMDebugInfoCodeView.a \
179 $LLVM_BUILD/lib
/libLLVMDebuginfod.a \
180 $LLVM_BUILD/lib
/libLLVMDemangle.a \
181 $LLVM_BUILD/lib
/libLLVMMC.a \
182 $LLVM_BUILD/lib
/libLLVMTextAPI.a \
188 $OPT -internalize -internalize-public-api-list=${SYMBOLIZER_API_LIST} all.
bc -o opt.
bc
189 $CC $FLAGS -fno-lto -c opt.
bc -o symbolizer.o
191 echo "Checking undefined symbols..."
192 nm
-f posix
-g symbolizer.o | cut
-f 1,2 -d \ | LC_COLLATE
=C
sort -u > undefined.new
193 (diff -u $SCRIPT_DIR/global_symbols.txt undefined.new |
grep -E "^\+[^+]") && \
194 (echo "Failed: unexpected symbols"; exit 1)
197 objdump
-f $1 |
grep -m1 -Po "(?<=file format ).*$"
200 SYMBOLIZER_FORMAT
=$
(arch symbolizer.o
)
201 echo "Injecting $SYMBOLIZER_FORMAT symbolizer..."
202 for A
in $TARGE_DIR/libclang_rt.
*san
*.a
; do
204 if [[ "$A_FORMAT" != "$SYMBOLIZER_FORMAT" ]] ; then
207 (nm
-u $A 2>/dev
/null |
grep -E "__sanitizer_symbolize_code" >/dev
/null
) ||
continue
209 $AR rcs
$A symbolizer.o