├── __init__.py ├── hextype ├── __init__.py ├── test │ ├── Makefile │ └── test01.cc └── hextype.py ├── lowfat ├── __init__.py ├── config │ ├── sizes2.cfg │ ├── Makefile │ ├── sizes.cfg │ ├── lowfat-check-config.c │ ├── lowfat-ptr-info.c │ ├── lowfat.errs │ └── lowfat-config.c ├── blacklist.txt ├── modern_compiler-rt.patch ├── legacy_compiler-rt.patch ├── bug81066.patch ├── clang.patch └── lowfat.py ├── clang ├── asan │ ├── __init__.py │ ├── blacklist.txt │ ├── asan.py │ └── spec2006-asan.patch ├── msan │ ├── __init__.py │ ├── dealII.patch │ └── msan.py ├── ubsan │ ├── __init__.py │ └── ubsan.py ├── cfi │ ├── __init__.py │ ├── all.py │ ├── fwdedge.py │ ├── cast.py │ └── common.py ├── __init__.py └── common.py ├── dangsan ├── __init__.py ├── test │ ├── Makefile │ └── test01.c ├── SPEC-CPU2006-dealII-stddef.patch ├── SPEC-CPU2006-soplex-dangsan-mask.patch └── dangsan.py ├── hexvasan ├── __init__.py ├── hexvasan.py └── clang.patch ├── typesan ├── __init__.py ├── test │ ├── Makefile │ └── test01.cc ├── GPERFTOOLS_SPEEDUP.patch ├── typesan.py ├── clang.patch └── GPERFTOOLS_TYPESAN.patch ├── valgrind ├── __init__.py ├── valgrind.py └── memcheck.py ├── util ├── __init__.py ├── svn.py ├── git.py ├── misc.py ├── test.py ├── spec.py └── llvm.py ├── .gitignore ├── benchmark.py ├── README.md └── CPU2006.patch /__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /hextype/__init__.py: -------------------------------------------------------------------------------- 1 | from hextype import * -------------------------------------------------------------------------------- /lowfat/__init__.py: -------------------------------------------------------------------------------- 1 | from lowfat import * 2 | -------------------------------------------------------------------------------- /clang/asan/__init__.py: -------------------------------------------------------------------------------- 1 | from asan import * 2 | -------------------------------------------------------------------------------- /clang/msan/__init__.py: -------------------------------------------------------------------------------- 1 | from msan import * 2 | -------------------------------------------------------------------------------- /clang/ubsan/__init__.py: -------------------------------------------------------------------------------- 1 | from ubsan import * 2 | -------------------------------------------------------------------------------- /dangsan/__init__.py: -------------------------------------------------------------------------------- 1 | from dangsan import * 2 | -------------------------------------------------------------------------------- /hexvasan/__init__.py: -------------------------------------------------------------------------------- 1 | from hexvasan import * 2 | -------------------------------------------------------------------------------- /typesan/__init__.py: -------------------------------------------------------------------------------- 1 | from typesan import * 2 | -------------------------------------------------------------------------------- /clang/asan/blacklist.txt: -------------------------------------------------------------------------------- 1 | fun:biari_init_context 2 | -------------------------------------------------------------------------------- /valgrind/__init__.py: -------------------------------------------------------------------------------- 1 | import memcheck as memcheck 2 | -------------------------------------------------------------------------------- /clang/cfi/__init__.py: -------------------------------------------------------------------------------- 1 | import common 2 | import all 3 | import cast 4 | import fwdedge 5 | -------------------------------------------------------------------------------- /util/__init__.py: -------------------------------------------------------------------------------- 1 | import git 2 | import llvm 3 | import spec 4 | import test 5 | from misc import * 6 | -------------------------------------------------------------------------------- /clang/__init__.py: -------------------------------------------------------------------------------- 1 | import asan as asan 2 | import msan as msan 3 | import ubsan as ubsan 4 | import cfi as cfi 5 | -------------------------------------------------------------------------------- /util/svn.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | 4 | def checkout(rev, repo, dir): 5 | if rev != '': 6 | rev = '-r' + rev 7 | p = subprocess.Popen(' '.join(['svn', 'co', rev, repo, dir]), shell=True) 8 | p.wait() 9 | -------------------------------------------------------------------------------- /dangsan/test/Makefile: -------------------------------------------------------------------------------- 1 | all: test01.dangsan 2 | 3 | %.o : %.c 4 | $(CC) $(CFLAGS) -o $@ -c $< 5 | 6 | %.dangsan : %.o 7 | $(LD) $(LDFLAGS) -o $@ $< 8 | 9 | .PHONY: clean test 10 | 11 | test: 12 | ./test01.dangsan 13 | 14 | clean: 15 | $(RM) *.dangsan *.o 16 | -------------------------------------------------------------------------------- /hextype/test/Makefile: -------------------------------------------------------------------------------- 1 | all: test01.hextype 2 | 3 | %.o: %.cc 4 | $(CXX) $(CXXFLAGS) -o $@ -c $< 5 | 6 | %.hextype : %.o 7 | $(CXX) $(LDFLAGS) -o $@ $< 8 | 9 | .PHONY: test clean 10 | 11 | test: 12 | ./test01.hextype 13 | 14 | clean: 15 | $(RM) *.hextype *.o 16 | -------------------------------------------------------------------------------- /typesan/test/Makefile: -------------------------------------------------------------------------------- 1 | all: test01.typesan 2 | 3 | %.o: %.cc 4 | $(CXX) $(CXXFLAGS) -o $@ -c $< 5 | 6 | %.typesan : %.o 7 | $(CXX) $(LDFLAGS) -o $@ $< 8 | 9 | .PHONY: test clean 10 | 11 | test: 12 | ./test01.typesan 13 | 14 | clean: 15 | $(RM) *.typesan *.o 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .\#* 2 | \#* 3 | *~ 4 | *.swp 5 | .idea 6 | *.pyc 7 | cpu2006 8 | speccpu2006-1.2.iso 9 | asan-*/ 10 | msan-*/ 11 | ubsan-*/ 12 | dangsan-*/ 13 | lowfat-*/ 14 | hextype-*/ 15 | hexvasan-*/ 16 | llvm-*/ 17 | softboundcets-*/ 18 | caver-*/ 19 | typesan-*/ 20 | tysan-*/ 21 | memcheck-*/ 22 | drmemory-*/ 23 | cfi-*/ 24 | -------------------------------------------------------------------------------- /lowfat/config/sizes2.cfg: -------------------------------------------------------------------------------- 1 | 16 2 | 32 3 | 64 4 | 128 5 | 256 6 | 512 7 | 1024 8 | 2048 9 | 4096 10 | 8192 11 | 16384 12 | 32768 13 | 65536 14 | 131072 15 | 262144 16 | 524288 17 | 1048576 18 | 2097152 19 | 4194304 20 | 8388608 21 | 16777216 22 | 33554432 23 | 67108864 24 | 134217728 25 | 268435456 26 | 536870912 27 | 1073741824 28 | 2147483648 29 | 4294967296 30 | 8589934592 31 | 17179869184 32 | 34359738368 33 | -------------------------------------------------------------------------------- /dangsan/SPEC-CPU2006-dealII-stddef.patch: -------------------------------------------------------------------------------- 1 | --- ./benchspec/CPU2006/447.dealII/src/include/lac/block_vector.h.orig 2016-11-17 21:40:18.088695507 +0100 2 | +++ ./benchspec/CPU2006/447.dealII/src/include/lac/block_vector.h 2016-11-17 21:37:42.698760418 +0100 3 | @@ -14,6 +14,7 @@ 4 | #define __deal2__block_vector_h 5 | 6 | 7 | +#include 8 | #include 9 | #include 10 | #include 11 | -------------------------------------------------------------------------------- /clang/cfi/all.py: -------------------------------------------------------------------------------- 1 | import os 2 | import util 3 | import clang 4 | import common 5 | 6 | 7 | command = 'cfi' 8 | configs = common.configs 9 | CFI_ALL_OPTIONS = ['cfi'] 10 | 11 | 12 | def test(config): 13 | return True 14 | 15 | 16 | def setup(config): 17 | common.setup(command, config, CFI_ALL_OPTIONS) 18 | 19 | 20 | def clean(config): 21 | clang.common.clean(config) 22 | 23 | 24 | def run(config): 25 | common.run(command, config) 26 | -------------------------------------------------------------------------------- /util/git.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | 4 | def clone(repo, options=[]): 5 | print 'cloning ' + repo + '...' 6 | cmd = ['git', 'clone'] 7 | cmd.extend(options) 8 | cmd.append(repo) 9 | subprocess.check_output(cmd) 10 | 11 | 12 | def checkout(commit): 13 | p = subprocess.Popen('git checkout ' + commit, shell=True) 14 | p.wait() 15 | 16 | 17 | def patch(diff): 18 | p = subprocess.Popen('git apply --ignore-whitespace ' + diff, shell=True) 19 | p.wait() 20 | -------------------------------------------------------------------------------- /lowfat/config/Makefile: -------------------------------------------------------------------------------- 1 | lowfat-config: lowfat-config.c 2 | $(CC) -o lowfat-config lowfat-config.c -lm -lpthread -O2 3 | 4 | lowfat-check-config: lowfat-check-config.c 5 | $(CC) -o lowfat-check-config lowfat-check-config.c -lm -lpthread -O2 6 | 7 | lowfat-ptr-info: lowfat-ptr-info.c 8 | $(CC) -o lowfat-ptr-info lowfat-ptr-info.c -lm -lpthread -O2 9 | 10 | clean: 11 | rm -f lowfat-config lowfat-check-config lowfat-ptr-info *.o *.i *.s *.ii \ 12 | lowfat.ld lowfat2.ld lowfat_config.h lowfat_config.c lowfat_config2.c 13 | 14 | -------------------------------------------------------------------------------- /clang/cfi/fwdedge.py: -------------------------------------------------------------------------------- 1 | import os 2 | import util 3 | import clang 4 | import common 5 | 6 | 7 | command = 'cfi-forward-edge' 8 | configs = common.configs 9 | CFI_FORWARD_EDGE_OPTIONS = [ 10 | 'cfi-nvcall', 11 | 'cfi-vcall', 12 | 'cfi-icall' 13 | ] 14 | 15 | 16 | def test(config): 17 | return True 18 | 19 | 20 | def setup(config): 21 | common.setup(command, config, CFI_FORWARD_EDGE_OPTIONS) 22 | 23 | 24 | def clean(config): 25 | clang.common.clean(config) 26 | 27 | 28 | def run(config): 29 | common.run(command, config) 30 | -------------------------------------------------------------------------------- /clang/cfi/cast.py: -------------------------------------------------------------------------------- 1 | import os 2 | import util 3 | import clang 4 | import common 5 | 6 | 7 | command = 'cfi-cast' 8 | configs = common.configs 9 | 10 | # only the ones enabled with the sanitizer group -fsanitize=cfi 11 | CFI_CAST_OPTIONS = [ 12 | 'cfi-unrelated-cast', 13 | 'cfi-derived-cast' 14 | ] 15 | 16 | 17 | def test(config): 18 | return True 19 | 20 | 21 | def setup(config): 22 | common.setup(command, config, CFI_CAST_OPTIONS) 23 | 24 | 25 | def clean(config): 26 | clang.common.clean(config) 27 | 28 | 29 | def run(config): 30 | common.run(command, config) 31 | -------------------------------------------------------------------------------- /util/misc.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | 4 | def run(cmd_str): 5 | p = subprocess.Popen(cmd_str, shell=True) 6 | p.wait() 7 | 8 | 9 | def stdout(cmd_list): 10 | p = subprocess.Popen(cmd_list, stdout=subprocess.PIPE) 11 | stdout = p.communicate()[0] 12 | return stdout 13 | 14 | 15 | def configure(options): 16 | run('./configure ' + options) 17 | 18 | 19 | def make(target=''): 20 | run('make ' + target) 21 | 22 | 23 | def patch(patch, options='-p1'): 24 | run('patch ' + options + ' <' + patch) 25 | 26 | 27 | def download(url): 28 | run('wget ' + url) 29 | 30 | 31 | def untar(tarball): 32 | run('tar -xvf ' + tarball) 33 | -------------------------------------------------------------------------------- /valgrind/valgrind.py: -------------------------------------------------------------------------------- 1 | import shutil 2 | import util 3 | 4 | 5 | VALGRIND_VER = '3.13.0' # Latest version available as of 4 Mar 2018 6 | # Announced on 14 June 2017 7 | # http://valgrind.org/downloads 8 | VALGRIND_URL_FORMAT = 'ftp://sourceware.org/pub/valgrind/valgrind-VER.tar.bz2' 9 | 10 | 11 | def download(untar_dir): 12 | valgrind_release_url = VALGRIND_URL_FORMAT.replace('VER', VALGRIND_VER) 13 | util.download(valgrind_release_url) 14 | 15 | valgrind_tarball = 'valgrind-VER.tar.bz2'.replace('VER', VALGRIND_VER) 16 | util.untar(valgrind_tarball) 17 | 18 | shutil.move('valgrind-VER'.replace('VER', VALGRIND_VER), untar_dir) 19 | -------------------------------------------------------------------------------- /lowfat/config/sizes.cfg: -------------------------------------------------------------------------------- 1 | 16 2 | 32 3 | 48 4 | 64 5 | 80 6 | 96 7 | 112 8 | 128 9 | 144 10 | 160 11 | 192 12 | 224 13 | 256 14 | 272 15 | 320 16 | 384 17 | 448 18 | 512 19 | 528 20 | 640 21 | 768 22 | 896 23 | 1024 24 | 1040 25 | 1280 26 | 1536 27 | 1792 28 | 2048 29 | 2064 30 | 2560 31 | 3072 32 | 3584 33 | 4096 34 | 4112 35 | 5120 36 | 6144 37 | 7168 38 | 8192 39 | 8208 40 | 10240 41 | 12288 42 | 16384 43 | 32768 44 | 65536 45 | 131072 46 | 262144 47 | 524288 48 | 1048576 49 | 2097152 50 | 4194304 51 | 8388608 52 | 16777216 53 | 33554432 54 | 67108864 55 | 134217728 56 | 268435456 57 | 536870912 58 | 1073741824 59 | 2147483648 60 | 4294967296 61 | 8589934592 62 | 17179869184 63 | 34359738368 64 | 68719476736 65 | -------------------------------------------------------------------------------- /util/test.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | 4 | 5 | def create_shrc(dir, cc, cxx, ld, cflags='', cxxflags='', ldflags=''): 6 | cwd = os.getcwd() 7 | os.chdir(dir) 8 | 9 | lines = [] 10 | lines.append('export CC="%s"' % cc) 11 | lines.append('export CXX="%s"' % cxx) 12 | lines.append('export LD="%s"' % ld) 13 | lines.append('export CFLAGS="%s"' % cflags) 14 | lines.append('export CXXFLAGS="%s"' % cxxflags) 15 | lines.append('export LDFLAGS="%s"' % ldflags) 16 | 17 | try: 18 | shrc = open(os.path.join(dir, 'shrc'), 'w') 19 | shrc.write('\n'.join(lines)) 20 | finally: 21 | print os.path.abspath(shrc.name) 22 | shrc.close() 23 | 24 | os.chdir(cwd) 25 | -------------------------------------------------------------------------------- /hextype/test/test01.cc: -------------------------------------------------------------------------------- 1 | // Illegal based to derived casting of a heap allocated object 2 | #include 3 | 4 | class Base { 5 | public: 6 | Base() {} 7 | virtual void print() { 8 | std::cout << "Base" << std::endl; 9 | } 10 | }; 11 | 12 | class Derived : public Base { 13 | private: 14 | int extra; 15 | public: 16 | Derived() : Base() {} 17 | virtual void print() { 18 | std::cout << "Derived" << std::endl; 19 | } 20 | }; 21 | 22 | __attribute__((noinline)) 23 | Derived *illegal_cast(Base *b) { 24 | return static_cast(b); 25 | } 26 | 27 | int main() { 28 | Base *b = new Base(); 29 | b->print(); 30 | 31 | Derived *d = illegal_cast(b); 32 | d->print(); 33 | 34 | delete b; 35 | } 36 | -------------------------------------------------------------------------------- /typesan/test/test01.cc: -------------------------------------------------------------------------------- 1 | // Illegal based to derived casting of a heap allocated object 2 | #include 3 | 4 | class Base { 5 | public: 6 | Base() {} 7 | virtual void print() { 8 | std::cout << "Base" << std::endl; 9 | } 10 | }; 11 | 12 | class Derived : public Base { 13 | private: 14 | int extra; 15 | public: 16 | Derived() : Base() {} 17 | virtual void print() { 18 | std::cout << "Derived" << std::endl; 19 | } 20 | }; 21 | 22 | __attribute__((noinline)) 23 | Derived *illegal_cast(Base *b) { 24 | return static_cast(b); 25 | } 26 | 27 | int main() { 28 | Base *b = new Base(); 29 | b->print(); 30 | 31 | Derived *d = illegal_cast(b); 32 | d->print(); 33 | 34 | delete b; 35 | } 36 | -------------------------------------------------------------------------------- /clang/msan/dealII.patch: -------------------------------------------------------------------------------- 1 | diff -ru a/benchspec/CPU2006/447.dealII/src/include/grid/tria_accessor.h b/benchspec/CPU2006/447.dealII/src/include/grid/tria_accessor.h 2 | --- a/benchspec/CPU2006/447.dealII/src/include/grid/tria_accessor.h 2005-06-02 19:43:52.000000000 -0700 3 | +++ b/benchspec/CPU2006/447.dealII/src/include/grid/tria_accessor.h 2018-03-27 14:32:16.300115046 -0700 4 | @@ -36,11 +36,11 @@ 5 | template class TriaObjectAccessor<3, dim>; 6 | 7 | 8 | -namespace std 9 | -{ 10 | - template 11 | - struct pair; 12 | -} 13 | +// namespace std 14 | +// { 15 | +// template 16 | +// struct pair; 17 | +// } 18 | 19 | // note: the file tria_accessor.templates.h is included at the end of 20 | // this file. this includes a lot of templates. originally, this was 21 | -------------------------------------------------------------------------------- /dangsan/test/test01.c: -------------------------------------------------------------------------------- 1 | // Invalidation of heap-stored pointers 2 | #include 3 | #include 4 | 5 | __attribute__ ((noinline)) 6 | void store_ptrs(int **pp, size_t numptrs) { 7 | for (unsigned i=0; i -1: 39 | print 'running ' + config + '...' 40 | 41 | spec_cfg = '-'.join([command, config]) + '.cfg' 42 | 43 | print 'running spec2006 cpu benchmark %s using %s...' % (', '.join(benchmarks), spec_cfg) 44 | 45 | util.spec.runspec(config=os.path.abspath(spec_cfg), 46 | benchmarks=benchmarks) 47 | -------------------------------------------------------------------------------- /lowfat/modern_compiler-rt.patch: -------------------------------------------------------------------------------- 1 | diff --git a/lib/lowfat/CMakeLists.txt b/lib/lowfat/CMakeLists.txt 2 | new file mode 100644 3 | index 0000000..b04fed1 4 | --- /dev/null 5 | +++ b/lib/lowfat/CMakeLists.txt 6 | @@ -0,0 +1,20 @@ 7 | +add_compiler_rt_component(lowfat) 8 | + 9 | +set(LOWFAT_SOURCES 10 | + lowfat.c) 11 | + 12 | +include_directories(..) 13 | + 14 | +set(LOWFAT_CFLAGS -std=gnu99 -m64 -I. -O2 -mbmi -mbmi2 -mlzcnt -mcmodel=large) 15 | + 16 | +add_compiler_rt_runtime(clang_rt.lowfat 17 | + STATIC 18 | + ARCHS x86_64 19 | + SOURCES ${LOWFAT_SOURCES} 20 | + CFLAGS ${LOWFAT_CFLAGS} 21 | + PARENT_TARGET lowfat) 22 | + 23 | +add_sanitizer_rt_symbols(clang_rt.lowfat) 24 | + 25 | +add_dependencies(compiler-rt lowfat) 26 | + 27 | diff --git a/lib/lowfat/CMakeLists.txt.modern b/lib/lowfat/CMakeLists.txt.modern 28 | deleted file mode 100644 29 | index b04fed1..0000000 30 | --- a/lib/lowfat/CMakeLists.txt.modern 31 | +++ /dev/null 32 | @@ -1,20 +0,0 @@ 33 | -add_compiler_rt_component(lowfat) 34 | - 35 | -set(LOWFAT_SOURCES 36 | - lowfat.c) 37 | - 38 | -include_directories(..) 39 | - 40 | -set(LOWFAT_CFLAGS -std=gnu99 -m64 -I. -O2 -mbmi -mbmi2 -mlzcnt -mcmodel=large) 41 | - 42 | -add_compiler_rt_runtime(clang_rt.lowfat 43 | - STATIC 44 | - ARCHS x86_64 45 | - SOURCES ${LOWFAT_SOURCES} 46 | - CFLAGS ${LOWFAT_CFLAGS} 47 | - PARENT_TARGET lowfat) 48 | - 49 | -add_sanitizer_rt_symbols(clang_rt.lowfat) 50 | - 51 | -add_dependencies(compiler-rt lowfat) 52 | - 53 | -------------------------------------------------------------------------------- /lowfat/legacy_compiler-rt.patch: -------------------------------------------------------------------------------- 1 | diff --git a/lib/lowfat/CMakeLists.txt b/lib/lowfat/CMakeLists.txt 2 | new file mode 100644 3 | index 0000000..49f500c 4 | --- /dev/null 5 | +++ b/lib/lowfat/CMakeLists.txt 6 | @@ -0,0 +1,20 @@ 7 | +add_compiler_rt_component(lowfat) 8 | + 9 | +set(LOWFAT_SOURCES 10 | + lowfat.c) 11 | + 12 | +include_directories(..) 13 | + 14 | +set(LOWFAT_CFLAGS -std=gnu99 -m64 -mno-bmi -mno-bmi2 -mno-lzcnt -I. -O2 -mcmodel=large) 15 | + 16 | +add_compiler_rt_runtime(clang_rt.lowfat 17 | + STATIC 18 | + ARCHS x86_64 19 | + SOURCES ${LOWFAT_SOURCES} 20 | + CFLAGS ${LOWFAT_CFLAGS} 21 | + PARENT_TARGET lowfat) 22 | + 23 | +add_sanitizer_rt_symbols(clang_rt.lowfat) 24 | + 25 | +add_dependencies(compiler-rt lowfat) 26 | + 27 | diff --git a/lib/lowfat/CMakeLists.txt.legacy b/lib/lowfat/CMakeLists.txt.legacy 28 | deleted file mode 100644 29 | index 49f500c..0000000 30 | --- a/lib/lowfat/CMakeLists.txt.legacy 31 | +++ /dev/null 32 | @@ -1,20 +0,0 @@ 33 | -add_compiler_rt_component(lowfat) 34 | - 35 | -set(LOWFAT_SOURCES 36 | - lowfat.c) 37 | - 38 | -include_directories(..) 39 | - 40 | -set(LOWFAT_CFLAGS -std=gnu99 -m64 -mno-bmi -mno-bmi2 -mno-lzcnt -I. -O2 -mcmodel=large) 41 | - 42 | -add_compiler_rt_runtime(clang_rt.lowfat 43 | - STATIC 44 | - ARCHS x86_64 45 | - SOURCES ${LOWFAT_SOURCES} 46 | - CFLAGS ${LOWFAT_CFLAGS} 47 | - PARENT_TARGET lowfat) 48 | - 49 | -add_sanitizer_rt_symbols(clang_rt.lowfat) 50 | - 51 | -add_dependencies(compiler-rt lowfat) 52 | - 53 | -------------------------------------------------------------------------------- /typesan/GPERFTOOLS_SPEEDUP.patch: -------------------------------------------------------------------------------- 1 | From 49ff49634debdcc13ebf2e00b8ceb53b3d8c9f72 Mon Sep 17 00:00:00 2001 2 | From: Istvan Haller 3 | Date: Thu, 17 Mar 2016 13:44:17 +0100 4 | Subject: [PATCH] Performance fix for SPEC. 5 | 6 | --- 7 | src/common.h | 4 ++-- 8 | src/tcmalloc.cc | 3 ++- 9 | 2 files changed, 4 insertions(+), 3 deletions(-) 10 | 11 | diff --git a/src/common.h b/src/common.h 12 | index c3484d3..15d7ee7 100644 13 | --- a/src/common.h 14 | +++ b/src/common.h 15 | @@ -91,13 +91,13 @@ static const size_t kPageShift = 16; 16 | static const size_t kNumClasses = kBaseClasses + 73; 17 | #else 18 | static const size_t kPageShift = 13; 19 | -static const size_t kNumClasses = kBaseClasses + 79; 20 | +static const size_t kNumClasses = kBaseClasses + 79 + 32; 21 | #endif 22 | 23 | static const size_t kMaxThreadCacheSize = 4 << 20; 24 | 25 | static const size_t kPageSize = 1 << kPageShift; 26 | -static const size_t kMaxSize = 256 * 1024; 27 | +static const size_t kMaxSize = 256 * 1024 * 2;; 28 | static const size_t kAlignment = 8; 29 | static const size_t kLargeSizeClass = 0; 30 | // For all span-lengths < kMaxPages we keep an exact-size list. 31 | diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc 32 | index b7d1913..387ba76 100644 33 | --- a/src/tcmalloc.cc 34 | +++ b/src/tcmalloc.cc 35 | @@ -1211,7 +1211,8 @@ ALWAYS_INLINE void* do_calloc(size_t n, size_t elem_size) { 36 | 37 | void* result = do_malloc_or_cpp_alloc(size); 38 | if (result != NULL) { 39 | - memset(result, 0, size); 40 | + if (size <= kMaxSize) 41 | + memset(result, 0, size); 42 | } 43 | return result; 44 | } 45 | -- 46 | 1.7.9.5 47 | 48 | -------------------------------------------------------------------------------- /clang/asan/asan.py: -------------------------------------------------------------------------------- 1 | import os 2 | import util 3 | import clang.common as common 4 | 5 | 6 | command = 'asan' 7 | configs = ['baseline-spec', 'spec'] 8 | 9 | 10 | def test(config): 11 | return True 12 | 13 | 14 | def setup(config): 15 | common.setup(config) 16 | 17 | # Create spec config file 18 | print 'creating spec config file...' 19 | 20 | spec_cfg = '-'.join([command, config]) + '.cfg' 21 | 22 | if os.path.exists(spec_cfg): 23 | os.remove(spec_cfg) 24 | 25 | cflags = list() 26 | cflags.append('-DPATCH_PERLBENCH_OVERFLOW') 27 | cflags.append('-DPATCH_H264REF_OVERFLOW') 28 | 29 | cxxflags = list() 30 | cxxflags.append('-DNO_OMNETPP_OPERATOR_NEW') 31 | 32 | if config == configs[1]: 33 | cflags.append('-fsanitize=address') 34 | cxxflags.append('-fsanitize=address') 35 | 36 | # workaround for global buffer overflow in 464.h264ref 37 | blacklist = os.path.join(os.path.dirname(__file__), 'blacklist.txt') 38 | cflags.append('-fsanitize-blacklist=%s' % blacklist) 39 | 40 | path = os.path.abspath(os.path.join('llvm-%s' % common.llvmver, 'bin')) 41 | cc = [os.path.join(path, 'clang')] 42 | cc.extend(cflags) 43 | cxx = [os.path.join(path, 'clang++')] 44 | cxx.extend(cxxflags) 45 | 46 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 47 | name='-'.join([command, config]), 48 | cc=' '.join(cc), cxx=' '.join(cxx), 49 | cxxportability=common.cxxportability) 50 | 51 | 52 | def clean(config): 53 | common.clean(config) 54 | 55 | 56 | def run(config): 57 | ASAN_OPTIONS = ['detect_leaks=0', 'alloc_dealloc_mismatch=0'] 58 | if config == configs[1]: 59 | os.environ['ASAN_OPTIONS'] = ':'.join(ASAN_OPTIONS) 60 | 61 | benchmarks = util.spec.all_benchmarks 62 | common.run(command, config, benchmarks) 63 | -------------------------------------------------------------------------------- /benchmark.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | import dangsan 4 | import lowfat 5 | import hextype 6 | import hexvasan 7 | import clang 8 | import typesan 9 | import valgrind 10 | 11 | 12 | tools = [dangsan, lowfat, hextype, hexvasan, clang.asan, clang.msan, 13 | clang.ubsan, clang.cfi.all, clang.cfi.cast, 14 | clang.cfi.fwdedge, typesan, valgrind.memcheck] 15 | 16 | 17 | def add_arguments(parser): 18 | subparsers = parser.add_subparsers(dest='command') 19 | 20 | for tool in tools: 21 | subparser = subparsers.add_parser(tool.command) 22 | subparser.add_argument('--setup', type=str, choices=tool.configs) 23 | subparser.add_argument('--test', type=str, choices=tool.configs) 24 | subparser.add_argument('--run', type=str, choices=tool.configs) 25 | subparser.add_argument('--clean', type=str, choices=tool.configs) 26 | 27 | 28 | def parse_arguments(args): 29 | tool = next(tool for tool in tools if tool.command == args.command) 30 | if tool: 31 | if args.setup: 32 | config = args.setup 33 | workdir = '-'.join([args.command, config]) 34 | if not os.path.exists(workdir): 35 | os.mkdir(workdir) 36 | os.chdir(workdir) 37 | tool.setup(config) 38 | elif args.test: 39 | config = args.test 40 | workdir = '-'.join([args.command, config]) 41 | os.chdir(workdir) 42 | tool.test(config) 43 | elif args.run: 44 | config = args.run 45 | workdir = '-'.join([args.command, config]) 46 | os.chdir(workdir) 47 | tool.run(config) 48 | elif args.clean: 49 | if raw_input('are you sure? (y/n)') == 'y': 50 | tool.clean(args.clean) 51 | 52 | 53 | def main(): 54 | parser = argparse.ArgumentParser() 55 | add_arguments(parser) 56 | args = parser.parse_args() 57 | parse_arguments(args) 58 | 59 | 60 | if __name__ == '__main__': 61 | main() 62 | -------------------------------------------------------------------------------- /lowfat/config/lowfat-check-config.c: -------------------------------------------------------------------------------- 1 | /* 2 | * _| _|_|_|_| _| 3 | * _| _|_| _| _| _| _| _|_|_| _|_|_|_| 4 | * _| _| _| _| _| _| _|_|_| _| _| _| 5 | * _| _| _| _| _| _| _| _| _| _| _| 6 | * _|_|_|_| _|_| _| _| _| _|_|_| _|_| 7 | * 8 | * Gregory J. Duck. 9 | * 10 | * Copyright (c) 2017 The National University of Singapore. 11 | * All rights reserved. 12 | * 13 | * This file is distributed under the University of Illinois Open Source 14 | * License. See the LICENSE file for details. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "lowfat_config.c" 28 | 29 | void *worker(void *arg) 30 | { 31 | pthread_t thread = pthread_self(); 32 | pid_t tid = syscall(SYS_gettid); 33 | pid_t *tid_ptr = (pid_t *)((uint8_t *)thread + LOWFAT_TID_OFFSET); 34 | if (tid != *tid_ptr) 35 | { 36 | fprintf(stderr, "error: thread-id offset (0x%x) is wrong!\n", 37 | LOWFAT_TID_OFFSET); 38 | exit(EXIT_FAILURE); 39 | } 40 | while (true) 41 | sleep(1); 42 | } 43 | 44 | int main(int argc, char **argv) 45 | { 46 | pthread_t thread; 47 | int err = pthread_create(&thread, NULL, worker, NULL); 48 | if (err != 0) 49 | { 50 | fprintf(stderr, "error: failed to create a thread (err=%d)\n", err); 51 | exit(EXIT_FAILURE); 52 | } 53 | err = pthread_detach(thread); 54 | if (err != 0) 55 | { 56 | fprintf(stderr, "error: failed to detach thread (err=%d)\n", err); 57 | exit(EXIT_FAILURE); 58 | } 59 | pthread_t *joinid_ptr = 60 | (pthread_t *)((uint8_t *)thread + LOWFAT_JOINID_OFFSET); 61 | if (*joinid_ptr != thread) 62 | { 63 | fprintf(stderr, "error: joinid offset (0x%x) is wrong!\n", 64 | LOWFAT_JOINID_OFFSET); 65 | exit(EXIT_FAILURE); 66 | } 67 | 68 | printf("OK\n"); 69 | return 0; 70 | } 71 | 72 | -------------------------------------------------------------------------------- /clang/cfi/common.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import util 4 | import clang 5 | 6 | 7 | binutils_tarball_format = 'binutils-VERSION.tar.bz2' 8 | binutils_url_format = 'http://ftp.gnu.org/gnu/binutils/TARBALL' 9 | binutils_version = '2.30' 10 | 11 | configs = ['baseline-spec-cpp', 'spec-cpp'] 12 | 13 | 14 | def prepare_gold(version): 15 | curdir = os.getcwd() 16 | binutils_tarball = binutils_tarball_format.replace('VERSION', version) 17 | binutils_url = binutils_url_format.replace('TARBALL', binutils_tarball) 18 | util.download(binutils_url) 19 | util.untar(binutils_tarball) 20 | os.chdir('binutils-VERSION'.replace('VERSION', version)) 21 | util.configure('--prefix=%s --enable-gold --enable-plugins --disable-werror' % curdir) 22 | util.make('-j4') 23 | util.make('-j4 all-gold') 24 | util.make('install') 25 | os.chdir(curdir) 26 | 27 | 28 | def setup(command, config, cfi_flags): 29 | workdir = os.getcwd() 30 | 31 | if not os.path.exists('bin/ld'): 32 | prepare_gold(binutils_version) 33 | os.remove('bin/ld') 34 | shutil.copy('bin/ld.gold', 'bin/ld') 35 | 36 | compile_flags = ['-DLLVM_BINUTILS_INCDIR=%s/include' % workdir] 37 | clang.common.setup(config, compile_flags) 38 | 39 | # Create spec config file 40 | print 'creating spec config file...' 41 | 42 | spec_cfg = '-'.join([command, config]) + '.cfg' 43 | 44 | if os.path.exists(spec_cfg): 45 | os.remove(spec_cfg) 46 | 47 | cflags = list() 48 | 49 | if config == configs[1]: 50 | cflags.append('-fsanitize=%s' % ','.join(cfi_flags)) 51 | cflags.append('-fno-sanitize-trap=%s' % ','.join(cfi_flags)) 52 | cflags.append('-fsanitize-recover=all') 53 | 54 | cflags.append('-flto') 55 | cflags.append('-fvisibility=hidden') 56 | 57 | path = os.path.abspath(os.path.join('llvm-%s' % clang.common.llvmver, 'bin')) 58 | cc = [os.path.join(path, 'clang')] 59 | cc.extend(cflags) 60 | cxx = [os.path.join(path, 'clang++')] 61 | cxx.extend(cflags) 62 | 63 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 64 | name='-'.join([command, config]), 65 | cc=' '.join(cc), cxx=' '.join(cxx), 66 | cxxportability=clang.common.cxxportability) 67 | 68 | 69 | def run(command, config): 70 | os.environ['PATH'] = ':'.join([os.path.abspath('bin'), os.environ['PATH']]) 71 | benchmarks = util.spec.cpp_benchmarks 72 | clang.common.run(command, config, benchmarks) 73 | -------------------------------------------------------------------------------- /valgrind/memcheck.py: -------------------------------------------------------------------------------- 1 | import os 2 | import util 3 | import clang 4 | import valgrind 5 | 6 | 7 | command = 'memcheck' 8 | configs = ['baseline-spec', 'spec'] 9 | llvmver = '6.0.0' 10 | 11 | 12 | def setup(config): 13 | workdir = os.path.abspath(os.getcwd()) 14 | 15 | if not os.path.exists('llvm'): 16 | util.llvm.download(llvmver, os.getcwd()) 17 | 18 | if not os.path.exists('llvm-' + llvmver): 19 | os.mkdir('llvm-' + llvmver) 20 | util.llvm.compile(src_dir=os.path.abspath('llvm'), 21 | build_dir=os.path.abspath('llvm-' + llvmver), 22 | install_dir=workdir) 23 | 24 | if config == configs[1]: 25 | if not os.path.exists('valgrind'): 26 | valgrind.download(os.path.abspath('valgrind')) 27 | 28 | if os.path.exists(os.path.join('bin', 'valgrind')): 29 | print('valgrind exists. skipping installation...') 30 | else: 31 | os.chdir('valgrind') 32 | util.configure('--prefix=' + workdir) 33 | util.make() 34 | util.make('install') 35 | os.chdir(workdir) 36 | 37 | # Create spec config file 38 | print 'creating spec config file...' 39 | 40 | spec_cfg = '-'.join([command, config]) + '.cfg' 41 | 42 | if os.path.exists(spec_cfg): 43 | os.remove(spec_cfg) 44 | 45 | cflags = list() 46 | 47 | valgrind_path = os.path.abspath(os.path.join('bin', 'valgrind')) 48 | spec_wrapper = '' 49 | if config == configs[1]: 50 | spec_wrapper = valgrind_path + ' --tool=memcheck' 51 | 52 | llvm_bin_path = os.path.join(workdir, 'llvm-' + llvmver, 'bin') 53 | 54 | cc = [os.path.join(llvm_bin_path, 'clang')] 55 | cc.extend(cflags) 56 | cxx = [os.path.join(llvm_bin_path, 'clang++')] 57 | cxx.extend(cflags) 58 | 59 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 60 | name='-'.join([command, config]), 61 | cc=' '.join(cc), cxx=' '.join(cxx), 62 | cld=' '.join(cxx), 63 | spec_wrapper=spec_wrapper, 64 | cxxportability=clang.common.cxxportability) 65 | 66 | 67 | def run(config): 68 | if config.find('spec') > -1: 69 | print 'running ' + config + '...' 70 | 71 | spec_cfg = '-'.join([command, config]) + '.cfg' 72 | benchmarks = util.spec.all_benchmarks 73 | benchmarks.remove('447.dealII') # takes too long time (more than 49 hours) 74 | 75 | print 'running spec2006 cpu benchmark %s using %s...' % (', '.join(benchmarks), spec_cfg) 76 | 77 | util.spec.runspec(config=os.path.abspath(spec_cfg), 78 | benchmarks=benchmarks) 79 | -------------------------------------------------------------------------------- /hexvasan/hexvasan.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import shutil 4 | import subprocess 5 | import util 6 | 7 | 8 | command = 'hexvasan' 9 | configs = ['baseline-spec', 'spec'] 10 | repo = 'https://github.com/HexHive/HexVASAN.git' 11 | llvm_commit = '4607999' 12 | clang_commit = 'c3709e7' 13 | compiler_rt_commit = '38631af' 14 | 15 | 16 | def test(config): 17 | return True 18 | 19 | 20 | def setup(config): 21 | workdir = os.getcwd() 22 | 23 | if not os.path.exists('llvm'): 24 | util.llvm.checkout(llvm_commit, clang_commit, compiler_rt_commit) 25 | 26 | if config == configs[1]: 27 | llvm_patch = os.path.join(os.path.dirname(__file__), 'llvm.patch') 28 | clang_patch = os.path.join(os.path.dirname(__file__), 'clang.patch') 29 | compilerrt_patch = os.path.join(os.path.dirname(__file__), 'compiler-rt.patch') 30 | 31 | os.chdir(os.path.join(workdir, 'llvm')) 32 | util.git.patch(llvm_patch) 33 | os.chdir(os.path.join(workdir, 'llvm/tools/clang')) 34 | util.git.patch(clang_patch) 35 | os.chdir(os.path.join(workdir, 'llvm/projects/compiler-rt')) 36 | util.git.patch(compilerrt_patch) 37 | os.chdir(workdir) 38 | 39 | if not os.path.exists('llvm-build'): 40 | os.mkdir('llvm-build') 41 | 42 | util.llvm.compile(src_dir=os.path.abspath('llvm'), 43 | build_dir='llvm-build', 44 | install_dir=os.getcwd()) 45 | 46 | # Create spec config file 47 | print 'creating spec config file...' 48 | 49 | spec_cfg = '-'.join([command, config]) + '.cfg' 50 | 51 | if os.path.exists(spec_cfg): 52 | os.remove(spec_cfg) 53 | 54 | path = os.path.join('llvm-build', 'bin') 55 | 56 | cflags = list() 57 | if config == configs[1]: 58 | cflags = ['-fsanitize=vasan'] 59 | 60 | cc = [os.path.abspath(os.path.join(path, 'clang'))] 61 | cc.extend(cflags) 62 | cxx = [os.path.abspath(os.path.join(path, 'clang++'))] 63 | cxx.extend(cflags) 64 | 65 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 66 | name='-'.join([command, config]), 67 | cc=' '.join(cc), cxx=' '.join(cxx), 68 | cld=' '.join(cxx)) 69 | 70 | 71 | def clean(config): 72 | workdir = '-'.join(['hexvasan', config]) 73 | if not os.path.exists(workdir): 74 | print 'nothing to clean' 75 | return 76 | 77 | shutil.rmtree(workdir) 78 | 79 | 80 | def run(config): 81 | if config.find('spec') > -1: 82 | print 'running ' + config + '...' 83 | 84 | spec_cfg = '-'.join([command, config]) + '.cfg' 85 | benchmarks = util.spec.all_benchmarks 86 | 87 | print 'running spec2006 cpu benchmark %s using %s...' % (', '.join(benchmarks), spec_cfg) 88 | 89 | util.spec.runspec(config=os.path.abspath(spec_cfg), benchmarks=benchmarks) 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SoK: Sanitizing for Security 2 | 3 | ## Preparing SPEC CPU2006 4 | 5 | * Install SPEC CPU2006 benchmark (see [instructions](https://www.spec.org/cpu2006/docs/install-guide-unix.html)) 6 | * Apply [CPU2006.patch](CPU2006.patch) 7 | * Set up environment variables and paths for SPEC 8 | 9 | ```bash 10 | cd 11 | . ./shrc 12 | ``` 13 | 14 | ## Sanitizers and configurations 15 | 16 | | Sanitizer | Configuration | Description | 17 | | --------- | ------------- | ----------- | 18 | | `memcheck` | `baseline-spec` | lvm/clang 6.0.0 | 19 | | | `spec` | Valgrind 3.13.0, binaries compiled with llvm/clang 6.0.0 | 20 | | `asan` | `baseline-spec` | llvm/clang 6.0.0 | 21 | | | `spec` | ASan bundled with llvm/clang 6.0.0 | 22 | | `lowfat` | `baseline-spec` | llvm/clang 4.0.0 | 23 | | | `spec` | LowFat [11671b0b](https://github.com/GJDuck/LowFat/commit/11671b0b9b3345cf48ba5e1770a25552cf424cce) | 24 | | `dangsan` | `baseline-spec` | llvm/clang r251286, binutils 2.26.1, gperftools c46eb1f3 + DangSan speedup patch | 25 | | | `spec` | DangSan [78006af3](https://github.com/vusec/dangsan/commit/78006af30db70e42df25b7d44352ec717f6b0802) | 26 | | `msan` | `baseline-spec` | llvm/clang 6.0.0 | 27 | | | `spec` | MSan bundled with llvm/clang 6.0.0 | 28 | | `typesan` | `baseline-spec-cpp` | llvm 8f4f26c9, clang d59a142e, compiler-rt 961e7872, gperftools c46eb1f3 | 29 | | | `spec-cpp` | TypeSan [fe25d436](https://github.com/vusec/typesan/commit/fe25d436f92faf0b1da6ca43ae9171681b8f7c06) | 30 | | `hextype` | `baseline-spec-cpp` | llvm 8f4f26c9c, clang d59a142e, compiler-rt 961e7872 | 31 | | | `spec-cpp` | HexType [64c5469c](https://github.com/HexHive/HexType/commit/64c5469c53bd6b79b404c1b203da8a114107ec96) | 32 | | `cfi` | `baseline-spec-cpp` | llvm/clang 6.0.0, binutils 2.30 | 33 | | | `spec-cpp` | Clang CFI bundled with llvm/clang 6.0.0 | 34 | | `hexvasan` | `baseline-spec` | llvm 4607999, clang c3709e7, compiler-rt 38631af | 35 | | | `spec` | HexVASAN [164b16e14](https://github.com/HexHive/HexVASAN/commit/164b16e14bd7524b36f4cc613143e50409bac7d5) | 36 | | `ubsan` | `baseline-spec` | llvm/clang 6.0.0 | 37 | | | `spec` | UBSan bundled with llvm/clang 6.0.0 | 38 | 39 | 40 | ```bash 41 | # List sanitizers 42 | python benchmark.py --help 43 | 44 | # List configurations 45 | python benchmark.py --help 46 | ``` 47 | 48 | ## Building sanitizers 49 | 50 | ```bash 51 | python benchmark.py --setup 52 | ``` 53 | 54 | ## Running benchmarks 55 | 56 | ```bash 57 | python benchmark.py --run 58 | ``` 59 | 60 | ## Citing our work 61 | 62 | If you use this benchmarking script in an academic work, please cite our [paper](https://www.computer.org/csdl/proceedings/sp/2019/6660/00/666000a187.pdf): 63 | 64 | ``` 65 | @inproceedings{song2019sanitizing, 66 | title = {{SoK}: Sanitizing for Security}, 67 | author = {Song, Dokyung and Lettner, Julian and Rajasekaran, Prabhu 68 | and Na, Yeoul and Volckaert, Stijn and Larsen, Per 69 | and Franz, Michael}, 70 | booktitle = {IEEE Symposium on Security and Privacy}, 71 | year = {2019} 72 | } 73 | ``` 74 | -------------------------------------------------------------------------------- /lowfat/bug81066.patch: -------------------------------------------------------------------------------- 1 | Index: lib/sanitizer_common/sanitizer_linux.h 2 | =================================================================== 3 | --- lib/sanitizer_common/sanitizer_linux.h 4 | +++ lib/sanitizer_common/sanitizer_linux.h 5 | @@ -21,17 +21,15 @@ 6 | #include "sanitizer_platform_limits_posix.h" 7 | 8 | struct link_map; // Opaque type returned by dlopen(). 9 | -struct sigaltstack; 10 | 11 | namespace __sanitizer { 12 | // Dirent structure for getdents(). Note that this structure is different from 13 | // the one in , which is used by readdir(). 14 | struct linux_dirent; 15 | 16 | // Syscall wrappers. 17 | uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); 18 | -uptr internal_sigaltstack(const struct sigaltstack* ss, 19 | - struct sigaltstack* oss); 20 | +uptr internal_sigaltstack(const void* ss, void* oss); 21 | uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, 22 | __sanitizer_sigset_t *oldset); 23 | 24 | Index: lib/sanitizer_common/sanitizer_linux.cc 25 | =================================================================== 26 | --- lib/sanitizer_common/sanitizer_linux.cc 27 | +++ lib/sanitizer_common/sanitizer_linux.cc 28 | @@ -631,8 +631,7 @@ 29 | } 30 | #endif 31 | 32 | -uptr internal_sigaltstack(const struct sigaltstack *ss, 33 | - struct sigaltstack *oss) { 34 | +uptr internal_sigaltstack(const void *ss, void *oss) { 35 | return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss); 36 | } 37 | 38 | Index: lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc 39 | =================================================================== 40 | --- lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc 41 | +++ lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc 42 | @@ -287,7 +287,7 @@ 43 | 44 | // Alternate stack for signal handling. 45 | InternalScopedBuffer handler_stack_memory(kHandlerStackSize); 46 | - struct sigaltstack handler_stack; 47 | + stack_t handler_stack; 48 | internal_memset(&handler_stack, 0, sizeof(handler_stack)); 49 | handler_stack.ss_sp = handler_stack_memory.data(); 50 | handler_stack.ss_size = kHandlerStackSize; 51 | Index: lib/tsan/rtl/tsan_platform_linux.cc 52 | =================================================================== 53 | --- lib/tsan/rtl/tsan_platform_linux.cc 54 | +++ lib/tsan/rtl/tsan_platform_linux.cc 55 | @@ -288,7 +288,7 @@ 56 | int ExtractResolvFDs(void *state, int *fds, int nfd) { 57 | #if SANITIZER_LINUX && !SANITIZER_ANDROID 58 | int cnt = 0; 59 | - __res_state *statp = (__res_state*)state; 60 | + struct __res_state *statp = (struct __res_state*)state; 61 | for (int i = 0; i < MAXNS && cnt < nfd; i++) { 62 | if (statp->_u._ext.nsaddrs[i] && statp->_u._ext.nssocks[i] != -1) 63 | fds[cnt++] = statp->_u._ext.nssocks[i]; 64 | Index: lib/esan/esan_sideline_linux.cpp 65 | =================================================================== 66 | --- lib/esan/esan_sideline_linux.cpp 67 | +++ lib/esan/esan_sideline_linux.cpp 68 | @@ -70,7 +70,7 @@ int SidelineThread::runSideline(void *Arg) { 69 | 70 | // Set up a signal handler on an alternate stack for safety. 71 | InternalScopedBuffer StackMap(SigAltStackSize); 72 | - struct sigaltstack SigAltStack; 73 | + stack_t SigAltStack; 74 | SigAltStack.ss_sp = StackMap.data(); 75 | SigAltStack.ss_size = SigAltStackSize; 76 | SigAltStack.ss_flags = 0; 77 | -------------------------------------------------------------------------------- /clang/msan/msan.py: -------------------------------------------------------------------------------- 1 | import os 2 | import util 3 | import clang.common as common 4 | 5 | 6 | command = 'msan' 7 | configs = ['baseline-spec', 'spec', 'spec-recover'] 8 | 9 | 10 | def test(config): 11 | return True 12 | 13 | 14 | def setup(config): 15 | common.setup(config=config) 16 | 17 | # Compile libcxx & libcxxabi 18 | projects_dir = os.path.join('llvm', 'projects') 19 | libcxx_dir = os.path.join(projects_dir, 'libcxx') 20 | libcxxabi_dir = os.path.join(projects_dir, 'libcxxabi') 21 | util.llvm.download_libcxx(version=common.llvmver, 22 | libcxx=not os.path.exists(libcxx_dir), 23 | libcxxabi=not os.path.exists(libcxxabi_dir)) 24 | 25 | if not os.path.exists('libcxx'): 26 | os.mkdir('libcxx') 27 | path = os.path.abspath(os.path.join('llvm-%s' % common.llvmver, 'bin')) 28 | os.environ['PATH'] = ':'.join([path, os.environ['PATH']]) 29 | 30 | options = [ 31 | '-DCMAKE_C_COMPILER=clang', 32 | '-DCMAKE_CXX_COMPILER=clang++' 33 | ] 34 | 35 | if config == configs[1]: 36 | options.append('-DLLVM_USE_SANITIZER=Memory') 37 | 38 | util.llvm.compile_libcxx(src_dir=os.path.abspath('llvm'), 39 | build_dir=os.path.abspath('libcxx'), 40 | install_dir=os.path.abspath(os.getcwd()), 41 | options=options) 42 | 43 | # Create spec config file 44 | print 'creating spec config file...' 45 | 46 | spec_cfg = '-'.join([command, config]) + '.cfg' 47 | 48 | if os.path.exists(spec_cfg): 49 | os.remove(spec_cfg) 50 | 51 | cflags = list() 52 | 53 | if config == configs[1] or config == configs[2]: 54 | cflags.append('-fsanitize=memory') 55 | 56 | if config == configs[2]: 57 | cflags.append('-fsanitize-recover=memory') 58 | 59 | libcxx_path = os.path.abspath('libcxx') 60 | 61 | cxxflags = list(cflags) 62 | cxxflags.append('-DNO_OMNETPP_OPERATOR_NEW') 63 | cxxflags.append('-DNO_DEALII_STD_PAIR') 64 | cxxflags.extend([ 65 | '-stdlib=libc++', 66 | '-I%s' % os.path.join(libcxx_path, 'include'), 67 | '-I%s' % os.path.join(libcxx_path, 'include', 'c++', 'v1') 68 | ]) 69 | 70 | path = os.path.abspath(os.path.join('llvm-%s' % common.llvmver, 'bin')) 71 | cc = [os.path.join(path, 'clang')] 72 | cc.extend(cflags) 73 | cxx = [os.path.join(path, 'clang++')] 74 | cxx.extend(cxxflags) 75 | 76 | extra_cxxlibs = [ 77 | '-L%s' % os.path.join(libcxx_path, 'lib'), 78 | '-Wl,-rpath=%s' % os.path.join(libcxx_path, 'lib'), 79 | '-lc++abi' 80 | ] 81 | 82 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 83 | name='-'.join([command, config]), 84 | cc=' '.join(cc), cxx=' '.join(cxx), 85 | extra_cxxlibs=' '.join(extra_cxxlibs), 86 | cxxportability=common.cxxportability) 87 | 88 | 89 | def clean(config): 90 | common.clean(config) 91 | 92 | 93 | def run(config): 94 | benchmarks = util.spec.all_benchmarks 95 | if config == configs[2]: 96 | os.environ['MSAN_OPTIONS'] = 'halt_on_error=0' 97 | benchmarks = ['403.gcc'] 98 | 99 | common.run(command, config, benchmarks) 100 | -------------------------------------------------------------------------------- /dangsan/SPEC-CPU2006-soplex-dangsan-mask.patch: -------------------------------------------------------------------------------- 1 | diff -Naur ./benchspec/CPU2006/450.soplex/src/idlist.h ./benchspec/CPU2006/450.soplex/src/idlist.h 2 | --- ./benchspec/CPU2006/450.soplex/src/idlist.h 2016-11-24 16:28:16.673199838 +0100 3 | +++ ./benchspec/CPU2006/450.soplex/src/idlist.h 2016-11-24 16:30:00.499666292 +0100 4 | @@ -269,6 +269,13 @@ 5 | } 6 | //@} 7 | 8 | + static T *moveptr(T *ptr, ptrdiff_t delta) 9 | + { 10 | + unsigned long mask = 0x7fffffffffffffffUL; 11 | + unsigned long newptr = reinterpret_cast(ptr) + delta; 12 | + unsigned long maskedptr = newptr & mask; 13 | + return reinterpret_cast(maskedptr); 14 | + } 15 | 16 | /**@name Miscellaneous */ 17 | //@{ 18 | @@ -285,8 +292,7 @@ 19 | IsList::move(delta); 20 | for (elem = last(); elem; elem = prev(elem)) 21 | if (elem != first()) 22 | - elem->prev() = reinterpret_cast( 23 | - reinterpret_cast(elem->prev()) + delta); 24 | + elem->prev() = moveptr(elem->prev(), delta); 25 | } 26 | } 27 | 28 | diff -Naur ./benchspec/CPU2006/450.soplex/src/islist.h ./benchspec/CPU2006/450.soplex/src/islist.h 29 | --- ./benchspec/CPU2006/450.soplex/src/islist.h 2016-11-24 16:28:16.673199838 +0100 30 | +++ ./benchspec/CPU2006/450.soplex/src/islist.h 2016-11-24 16:30:00.499666292 +0100 31 | @@ -340,6 +340,14 @@ 32 | } 33 | //@} 34 | 35 | + static T *moveptr(T *ptr, ptrdiff_t delta) 36 | + { 37 | + unsigned long mask = 0x7fffffffffffffffUL; 38 | + unsigned long newptr = reinterpret_cast(ptr) + delta; 39 | + unsigned long maskedptr = newptr & mask; 40 | + return reinterpret_cast(maskedptr); 41 | + } 42 | + 43 | /**@name Miscellaneous */ 44 | //@{ 45 | /// adjusts list pointers to a new memory address. 46 | @@ -356,11 +364,11 @@ 47 | if (the_first) 48 | { 49 | T* elem; 50 | - the_last = reinterpret_cast(reinterpret_cast(the_last) + delta); 51 | - the_first = reinterpret_cast(reinterpret_cast(the_first) + delta); 52 | + the_last = moveptr(the_last, delta); 53 | + the_first = moveptr(the_first, delta); 54 | for (elem = first(); elem; elem = next(elem)) 55 | if (elem != last()) 56 | - elem->next() = reinterpret_cast(reinterpret_cast(elem->next()) + delta); 57 | + elem->next() = moveptr(elem->next(), delta); 58 | } 59 | } 60 | 61 | diff -Naur ./benchspec/CPU2006/450.soplex/src/svset.cc ./benchspec/CPU2006/450.soplex/src/svset.cc 62 | --- ./benchspec/CPU2006/450.soplex/src/svset.cc 2016-11-24 16:28:16.677199779 +0100 63 | +++ ./benchspec/CPU2006/450.soplex/src/svset.cc 2016-11-24 17:38:39.284398866 +0100 64 | @@ -254,6 +254,14 @@ 65 | list.move(set.reMax(newmax)); 66 | } 67 | 68 | +static SVector::Element *moveptr(void *ptr, ptrdiff_t delta) 69 | +{ 70 | + unsigned long mask = 0x7fffffffffffffffUL; 71 | + unsigned long newptr = reinterpret_cast(ptr) + delta; 72 | + unsigned long maskedptr = newptr & mask; 73 | + return reinterpret_cast(maskedptr); 74 | +} 75 | + 76 | void SVSet::memRemax(int newmax) 77 | { 78 | ptrdiff_t delta = DataArray < SVector::Element > ::reMax(newmax); 79 | @@ -262,7 +270,7 @@ 80 | { 81 | for (DLPSV* ps = list.first(); ps; ps = list.next(ps)) 82 | { 83 | - SVector::Element * info = reinterpret_cast(reinterpret_cast(ps->mem()) + delta); 84 | + SVector::Element * info = moveptr(ps->mem(), delta); 85 | int sz = info->idx; 86 | int l_max = int( info->val ); 87 | assert(l_max >= sz ); 88 | -------------------------------------------------------------------------------- /clang/asan/spec2006-asan.patch: -------------------------------------------------------------------------------- 1 | diff -u -r ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/400.perlbench/src/perlio.c ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/400.perlbench/src/perlio.c 2 | --- ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/400.perlbench/src/perlio.c 2011-10-19 03:51:48.000000000 +0400 3 | +++ ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/400.perlbench/src/perlio.c 2013-02-28 14:36:26.535467963 +0400 4 | @@ -748,7 +748,7 @@ 5 | len = strlen(name); 6 | for (i = 0; i < PL_known_layers->cur; i++) { 7 | PerlIO_funcs *f = PL_known_layers->array[i].funcs; 8 | - if (memEQ(f->name, name, len) && f->name[len] == 0) { 9 | + if (!strcmp(f->name, name) && f->name[len] == 0) { 10 | PerlIO_debug("%.*s => %p\n", (int) len, name, (void*)f); 11 | return f; 12 | } 13 | diff -u -r ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/400.perlbench/src/sv.c ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/400.perlbench/src/sv.c 14 | --- ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/400.perlbench/src/sv.c 2011-10-19 03:51:49.000000000 +0400 15 | +++ ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/400.perlbench/src/sv.c 2013-02-28 14:36:21.125446508 +0400 16 | @@ -4104,6 +4104,25 @@ 17 | =cut 18 | */ 19 | 20 | +#undef __attribute__ 21 | +__attribute__((no_sanitize_address, noinline)) 22 | +char *move_no_asan(char *dest, const char *src, STRLEN len) { 23 | + char *d = (char*)dest; 24 | + char *s = (char*)src; 25 | + signed long i, signed_n = len; 26 | + if (d < s) { 27 | + for (i = 0; i < signed_n; ++i) 28 | + d[i] = s[i]; 29 | + } else { 30 | + if (d > s && signed_n > 0) 31 | + for (i = signed_n - 1; i >= 0 ; --i) { 32 | + d[i] = s[i]; 33 | + } 34 | + } 35 | + return dest; 36 | +} 37 | + 38 | +__attribute__((no_sanitize_address)) 39 | void 40 | Perl_sv_setpvn(pTHX_ register SV *sv, register const char *ptr, register STRLEN len) 41 | { 42 | @@ -4124,7 +4143,8 @@ 43 | 44 | SvGROW(sv, len + 1); 45 | dptr = SvPVX(sv); 46 | - Move(ptr,dptr,len,char); 47 | + move_no_asan(dptr, ptr, len); 48 | + // Move(ptr,dptr,len,char); 49 | dptr[len] = '\0'; 50 | SvCUR_set(sv, len); 51 | (void)SvPOK_only_UTF8(sv); /* validate pointer */ 52 | diff -u -r ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/464.h264ref/src/biariencode.c ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/464.h264ref/src/biariencode.c 53 | --- ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/464.h264ref/src/biariencode.c 2011-10-19 03:53:14.000000000 +0400 54 | +++ ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/464.h264ref/src/biariencode.c 2013-02-28 15:05:15.622307814 +0400 55 | @@ -327,6 +327,7 @@ 56 | * Initializes a given context with some pre-defined probability state 57 | ************************************************************************ 58 | */ 59 | +__attribute__((no_sanitize_address)) 60 | void biari_init_context (BiContextTypePtr ctx, const int* ini) 61 | { 62 | int pstate; 63 | diff -u -r ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/464.h264ref/src/mv-search.c ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/464.h264ref/src/mv-search.c 64 | --- ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/464.h264ref/src/mv-search.c 2011-10-19 03:53:14.000000000 +0400 65 | +++ ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/464.h264ref/src/mv-search.c 2013-02-28 15:14:41.214541085 +0400 66 | @@ -1016,7 +1016,7 @@ 67 | int 68 | SATD (int* diff, int use_hadamard) 69 | { 70 | - int k, satd = 0, m[16], dd, d[16]; 71 | + int k, satd = 0, m[16], dd, d[16+1]; 72 | 73 | if (use_hadamard) 74 | { 75 | diff -u -r ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/471.omnetpp/src/libs/cmdenv/heap.cc ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/471.omnetpp/src/libs/cmdenv/heap.cc 76 | --- ORIG_SPEC_CPU2006v1.2/benchspec/CPU2006/471.omnetpp/src/libs/cmdenv/heap.cc 2011-10-19 03:53:19.000000000 +0400 77 | +++ ASAN_SPEC_CPU2006v1.2/benchspec/CPU2006/471.omnetpp/src/libs/cmdenv/heap.cc 2013-02-28 14:36:05.855385945 +0400 78 | @@ -295,6 +295,7 @@ 79 | } 80 | #endif 81 | 82 | +#if 0 // Asan can not link if there is a use-defined operator new 83 | void *operator new(size_t m) 84 | { 85 | #ifdef HEAPCHECK 86 | @@ -400,3 +401,4 @@ 87 | if(id==breakat) brk("DELETE"); 88 | #endif 89 | } 90 | +#endif 91 | -------------------------------------------------------------------------------- /lowfat/config/lowfat-ptr-info.c: -------------------------------------------------------------------------------- 1 | /* 2 | * _| _|_|_|_| _| 3 | * _| _|_| _| _| _| _| _|_|_| _|_|_|_| 4 | * _| _| _| _| _| _| _|_|_| _| _| _| 5 | * _| _| _| _| _| _| _| _| _| _| _| 6 | * _|_|_|_| _|_| _| _| _| _|_|_| _|_| 7 | * 8 | * Gregory J. Duck. 9 | * 10 | * Copyright (c) 2017 The National University of Singapore. 11 | * All rights reserved. 12 | * 13 | * This file is distributed under the University of Illinois Open Source 14 | * License. See the LICENSE file for details. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "lowfat_config.c" 24 | 25 | /* 26 | * Slow definitions that do not depend on the LowFat runtime system: 27 | */ 28 | 29 | static size_t lowfat_index(const void *ptr) 30 | { 31 | return (uintptr_t)ptr / _LOWFAT_REGION_SIZE; 32 | } 33 | 34 | static void *lowfat_region(const void *ptr) 35 | { 36 | return (void *)(lowfat_index(ptr) * LOWFAT_REGION_SIZE); 37 | } 38 | 39 | static bool lowfat_is_ptr(const void *ptr) 40 | { 41 | size_t idx = lowfat_index(ptr); 42 | return (idx != 0 && idx <= LOWFAT_NUM_REGIONS+1); 43 | } 44 | 45 | static bool lowfat_is_heap_ptr(const void *ptr) 46 | { 47 | if (!lowfat_is_ptr(ptr)) 48 | return false; 49 | void *heap_lo = lowfat_region(ptr) + LOWFAT_HEAP_MEMORY_OFFSET; 50 | void *heap_hi = heap_lo + LOWFAT_HEAP_MEMORY_SIZE; 51 | return (ptr >= heap_lo && ptr < heap_hi); 52 | } 53 | 54 | static bool lowfat_is_stack_ptr(const void *ptr) 55 | { 56 | if (!lowfat_is_ptr(ptr)) 57 | return false; 58 | void *stack_lo = lowfat_region(ptr) + LOWFAT_STACK_MEMORY_OFFSET; 59 | void *stack_hi = stack_lo + LOWFAT_STACK_MEMORY_SIZE; 60 | return (ptr >= stack_lo && ptr < stack_hi); 61 | } 62 | 63 | static bool lowfat_is_global_ptr(const void *ptr) 64 | { 65 | if (!lowfat_is_ptr(ptr)) 66 | return false; 67 | void *global_lo = lowfat_region(ptr) + LOWFAT_GLOBAL_MEMORY_OFFSET; 68 | void *global_hi = global_lo + LOWFAT_GLOBAL_MEMORY_SIZE; 69 | return (ptr >= global_lo && ptr < global_hi); 70 | } 71 | 72 | static size_t lowfat_size(const void *ptr) 73 | { 74 | if (!lowfat_is_ptr(ptr)) 75 | return SIZE_MAX; 76 | else 77 | return lowfat_sizes[lowfat_index(ptr)-1]; 78 | } 79 | 80 | static size_t lowfat_magic(const void *ptr) 81 | { 82 | size_t idx = lowfat_index(ptr); 83 | if (!lowfat_is_ptr(ptr)) 84 | return 0; 85 | else 86 | return lowfat_magics[lowfat_index(ptr)-1]; 87 | } 88 | 89 | static void *lowfat_base(const void *ptr) 90 | { 91 | uintptr_t iptr = (uintptr_t)ptr; 92 | size_t size = lowfat_size(ptr); 93 | iptr -= iptr % size; 94 | return (void *)iptr; 95 | } 96 | 97 | /* 98 | * Main. 99 | */ 100 | int main(int argc, char **argv) 101 | { 102 | if (argc != 2) 103 | { 104 | fprintf(stderr, "usage: %s ptr\n", argv[0]); 105 | return EXIT_FAILURE; 106 | } 107 | void *ptr = NULL; 108 | if (argv[1][0] == '0' && argv[1][1] == 'x') 109 | ptr = (void *)strtoull(argv[1], NULL, 16); 110 | else 111 | ptr = (void *)strtoull(argv[1], NULL, 10); 112 | const char *type = 113 | (lowfat_is_heap_ptr(ptr)? "heap": 114 | (lowfat_is_stack_ptr(ptr)? "stack": 115 | (lowfat_is_global_ptr(ptr)? "global": 116 | (lowfat_is_ptr(ptr)? "unused": "nonfat")))); 117 | printf("ptr = %p\n", ptr); 118 | printf("type = %s\n", type); 119 | printf("region = #%zu (%p)\n", lowfat_index(ptr), lowfat_region(ptr)); 120 | printf("base = %p\n", lowfat_base(ptr)); 121 | printf("size = %zu (0x%zx)\n", lowfat_size(ptr), lowfat_size(ptr)); 122 | printf("magic = %zu (0x%zx)\n", lowfat_magic(ptr), lowfat_magic(ptr)); 123 | printf("offset = %zu\n", ptr - lowfat_base(ptr)); 124 | return 0; 125 | } 126 | 127 | -------------------------------------------------------------------------------- /hextype/hextype.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import subprocess 4 | import util 5 | 6 | 7 | command = 'hextype' 8 | configs = ['baseline-spec-cpp', 'spec-cpp'] 9 | hextype_repo = 'https://github.com/HexHive/HexType.git' 10 | hextype_commit = '64c5469c53bd6b79b404c1b203da8a114107ec96' 11 | llvm_commit = '8f4f26c9c7fec12eb039be6b20313a51417c97bb' 12 | clang_commit = 'd59a142ef50bf041797143db71d2d4777fd32d27' 13 | compilerrt_commit = '961e78720a32929d7e4fc13a72d7266d59672c42' 14 | 15 | 16 | def test(config): 17 | cwd = os.getcwd() 18 | 19 | os.chdir('test') 20 | 21 | if not os.path.exists('shrc'): 22 | raise Exception('no shrc found in directory %s' % testdir) 23 | 24 | try: 25 | f = open('shrc', 'r') 26 | lines = f.readlines() 27 | for line in lines: 28 | (key, _, value) = line.partition('=') 29 | os.environ[key.split()[1]] = value.rstrip().replace('"', '') 30 | finally: 31 | f.close() 32 | 33 | util.make('clean') 34 | util.make() 35 | util.make('test') 36 | 37 | os.chdir(cwd) 38 | 39 | 40 | def setup(config): 41 | workdir = os.path.abspath(os.getcwd()) 42 | 43 | if not os.path.exists('HexType'): 44 | util.git.clone(hextype_repo) 45 | os.chdir('HexType') 46 | util.git.checkout(hextype_commit) 47 | os.chdir('..') 48 | 49 | if not os.path.exists('llvm'): 50 | util.llvm.checkout(llvm_commit, clang_commit, compilerrt_commit) 51 | 52 | # apply HexType patches 53 | if config == configs[1]: 54 | os.chdir('llvm') 55 | llvm_patch = os.path.join(os.path.dirname(__file__), 'llvm.patch') 56 | util.git.patch(llvm_patch) 57 | 58 | os.chdir(workdir) 59 | 60 | os.chdir('llvm/tools/clang') 61 | clang_patch = os.path.join(os.path.dirname(__file__), 'clang.patch') 62 | util.git.patch(clang_patch) 63 | 64 | os.chdir(workdir) 65 | 66 | os.chdir('llvm/projects/compiler-rt') 67 | compilerrt_patch = os.path.join(os.path.dirname(__file__), 'compiler-rt.patch') 68 | util.git.patch(compilerrt_patch) 69 | 70 | os.chdir(workdir) 71 | 72 | if not os.path.exists('llvm-build'): 73 | os.mkdir('llvm-build') 74 | util.llvm.compile(src_dir=os.path.abspath('llvm'), 75 | build_dir='llvm-build', 76 | install_dir=os.getcwd()) 77 | 78 | # Create spec config file 79 | print 'creating spec config file...' 80 | 81 | spec_cfg = '-'.join([command, config]) + '.cfg' 82 | 83 | os.chdir(workdir) 84 | 85 | if os.path.exists(spec_cfg): 86 | os.remove(spec_cfg) 87 | 88 | path = os.path.join('llvm-build', 'bin') 89 | 90 | cflags = [] 91 | 92 | if config == configs[1]: 93 | cflags.append('-fsanitize=hextype') 94 | cflags.append('-mllvm -handle-reinterpret-cast') 95 | cflags.append('-mllvm -handle-placement-new') 96 | cflags.append('-mllvm -stack-opt') 97 | cflags.append('-mllvm -safestack-opt') 98 | cflags.append('-mllvm -cast-obj-opt') 99 | cflags.append('-mllvm -inline-opt') 100 | cflags.append('-mllvm -compile-time-verify-opt') 101 | cflags.append('-mllvm -enhance-dynamic-cast') 102 | 103 | cc = [os.path.abspath(os.path.join(path, 'clang'))] 104 | cc.extend(cflags) 105 | cxx = [os.path.abspath(os.path.join(path, 'clang++'))] 106 | cxx.extend(cflags) 107 | 108 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 109 | name='-'.join([command, config]), 110 | cc=' '.join(cc), cxx=' '.join(cxx)) 111 | 112 | # create shrc for testing 113 | print('creating test directory...') 114 | 115 | if not os.path.exists('test'): 116 | testdir = os.path.join(os.path.dirname(__file__), 'test') 117 | shutil.copytree(testdir, os.path.join(workdir, 'test')) 118 | 119 | if os.path.exists('test/shrc'): 120 | os.remove('test/shrc') 121 | 122 | util.test.create_shrc( 123 | dir=os.path.abspath('test'), 124 | cc=' '.join(cc), cxx=' '.join(cxx), ld=' '.join(cxx) 125 | ) 126 | 127 | 128 | def clean(config): 129 | workdir = '-'.join(['hextype', config]) 130 | if not os.path.exists(workdir): 131 | print 'nothing to clean' 132 | return 133 | 134 | shutil.rmtree(workdir) 135 | 136 | 137 | def run(config): 138 | if config.find('spec') > -1: 139 | print 'running ' + config + '...' 140 | spec_cfg = '-'.join([command, config]) + '.cfg' 141 | benchmarks = util.spec.cpp_benchmarks 142 | 143 | print 'running spec2006 cpu benchmark %s using %s...' % (', '.join(benchmarks), spec_cfg) 144 | 145 | util.spec.runspec(config=os.path.abspath(spec_cfg), 146 | benchmarks=benchmarks) 147 | -------------------------------------------------------------------------------- /lowfat/clang.patch: -------------------------------------------------------------------------------- 1 | diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def 2 | index c81273e..c8df64c 100644 3 | --- a/include/clang/Basic/Sanitizers.def 4 | +++ b/include/clang/Basic/Sanitizers.def 5 | @@ -37,6 +37,8 @@ 6 | #define SANITIZER_GROUP(NAME, ID, ALIAS) 7 | #endif 8 | 9 | +// LowFat 10 | +SANITIZER("lowfat", LowFat) 11 | 12 | // AddressSanitizer 13 | SANITIZER("address", Address) 14 | diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h 15 | index 6206680..f005855 100644 16 | --- a/include/clang/Driver/SanitizerArgs.h 17 | +++ b/include/clang/Driver/SanitizerArgs.h 18 | @@ -46,6 +46,7 @@ class SanitizerArgs { 19 | /// Parses the sanitizer arguments from an argument list. 20 | SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args); 21 | 22 | + bool needsLowFatRT() const { return Sanitizers.has(SanitizerKind::LowFat); } 23 | bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); } 24 | bool needsSharedAsanRt() const { return AsanSharedRuntime; } 25 | bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } 26 | diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp 27 | index 1a95ff2..05bc16e 100644 28 | --- a/lib/Basic/Targets.cpp 29 | +++ b/lib/Basic/Targets.cpp 30 | @@ -3002,6 +3002,8 @@ bool X86TargetInfo::setFPMath(StringRef Name) { 31 | return false; 32 | } 33 | 34 | +#include "lowfat_config.h" 35 | + 36 | bool X86TargetInfo::initFeatureMap( 37 | llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, 38 | const std::vector &FeaturesVec) const { 39 | @@ -3010,6 +3012,14 @@ bool X86TargetInfo::initFeatureMap( 40 | if (getTriple().getArch() == llvm::Triple::x86_64) 41 | setFeatureEnabledImpl(Features, "sse2", true); 42 | 43 | + // LowFat assumes -mbmi -mbmi2 -mlzcnt so just enable it here: 44 | + // FIXME: better way of doing this? 45 | +#ifndef _LOWFAT_LEGACY 46 | + setFeatureEnabledImpl(Features, "lzcnt", true); 47 | + setFeatureEnabledImpl(Features, "bmi", true); 48 | + setFeatureEnabledImpl(Features, "bmi2", true); 49 | +#endif 50 | + 51 | const CPUKind Kind = getCPUKind(CPU); 52 | 53 | // Enable X87 for all X86 processors but Lakemont. 54 | diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp 55 | index d2ce6ea..d3cab3a 100644 56 | --- a/lib/CodeGen/BackendUtil.cpp 57 | +++ b/lib/CodeGen/BackendUtil.cpp 58 | @@ -255,6 +255,13 @@ static void addEfficiencySanitizerPass(const PassManagerBuilder &Builder, 59 | PM.add(createEfficiencySanitizerPass(Opts)); 60 | } 61 | 62 | +static void addLowFatPass(const PassManagerBuilder &Builder, 63 | + legacy::PassManagerBase &PM) { 64 | + PM.add(createPromoteMemoryToRegisterPass()); // Currently assumed. 65 | + PM.add(createLowFatPass()); 66 | + PM.add(createFunctionInliningPass()); // Inline LowFat instrumentation 67 | +} 68 | + 69 | static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple, 70 | const CodeGenOptions &CodeGenOpts) { 71 | TargetLibraryInfoImpl *TLII = new TargetLibraryInfoImpl(TargetTriple); 72 | @@ -416,6 +423,13 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, 73 | addEfficiencySanitizerPass); 74 | } 75 | 76 | + if (LangOpts.Sanitize.has(SanitizerKind::LowFat)) { 77 | + PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, 78 | + addLowFatPass); 79 | + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, 80 | + addLowFatPass); 81 | + } 82 | + 83 | // Set up the per-function pass manager. 84 | FPM.add(new TargetLibraryInfoWrapperPass(*TLII)); 85 | if (CodeGenOpts.VerifyModule) 86 | @@ -501,7 +515,10 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { 87 | .Case("kernel", llvm::CodeModel::Kernel) 88 | .Case("medium", llvm::CodeModel::Medium) 89 | .Case("large", llvm::CodeModel::Large) 90 | - .Case("default", llvm::CodeModel::Default) 91 | + .Case("default", (LangOpts.Sanitize.has(SanitizerKind::LowFat)? 92 | + (CodeGenOpts.RelocationModel == "pic"? 93 | + llvm::CodeModel::Large : llvm::CodeModel::Medium) : 94 | + llvm::CodeModel::Default)) 95 | .Default(~0u); 96 | assert(CodeModel != ~0u && "invalid code model!"); 97 | llvm::CodeModel::Model CM = static_cast(CodeModel); 98 | diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp 99 | index 6adc038..55e62b8 100644 100 | --- a/lib/Driver/ToolChain.cpp 101 | +++ b/lib/Driver/ToolChain.cpp 102 | @@ -690,6 +690,8 @@ SanitizerMask ToolChain::getSupportedSanitizers() const { 103 | getTriple().getArch() == llvm::Triple::wasm32 || 104 | getTriple().getArch() == llvm::Triple::wasm64) 105 | Res |= CFIICall; 106 | + if (getTriple().getArch() == llvm::Triple::x86_64) 107 | + Res |= LowFat; 108 | return Res; 109 | } 110 | 111 | diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp 112 | index 3c3d453..7100d33 100644 113 | --- a/lib/Driver/Tools.cpp 114 | +++ b/lib/Driver/Tools.cpp 115 | @@ -3334,6 +3334,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, 116 | } 117 | if (SanArgs.needsEsanRt()) 118 | StaticRuntimes.push_back("esan"); 119 | + if (SanArgs.needsLowFatRT()) 120 | + StaticRuntimes.push_back("lowfat"); 121 | } 122 | 123 | // Should be called before we add system libraries (C++ ABI, libstdc++/libc++, 124 | @@ -3371,6 +3373,17 @@ static bool addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, 125 | if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic) 126 | CmdArgs.push_back("-export-dynamic-symbol=__cfi_check"); 127 | 128 | + if (SanArgs.needsLowFatRT()) { 129 | + // Use the special LowFat linker script for globals: 130 | + CmdArgs.push_back("-T"); 131 | + CmdArgs.push_back("LowFat/lowfat.ld"); 132 | + // This works around a bug (?) where ld defaults to 2MB page sizes for 133 | + // custom sections, leading to very large executables. The following 134 | + // forces 4KB page sizes: 135 | + CmdArgs.push_back("-z"); 136 | + CmdArgs.push_back("max-page-size=0x1000"); 137 | + } 138 | + 139 | return !StaticRuntimes.empty(); 140 | } 141 | 142 | -------------------------------------------------------------------------------- /typesan/typesan.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import shutil 4 | import util 5 | 6 | 7 | command = 'typesan' 8 | configs = ['baseline-spec-cpp', 'spec-cpp'] 9 | typesan_repo = 'https://github.com/vusec/typesan.git' 10 | llvm_commit = '8f4f26c9c7fec12eb039be6b20313a51417c97bb' 11 | clang_commit = 'd59a142ef50bf041797143db71d2d4777fd32d27' 12 | compilerrt_commit = '961e78720a32929d7e4fc13a72d7266d59672c42' 13 | gperftools_repo = 'https://github.com/gperftools/gperftools.git' 14 | gperftools_commit = 'c46eb1f3d2f7a2bdc54a52ff7cf5e7392f5aa668' 15 | 16 | 17 | def test(config): 18 | cwd = os.getcwd() 19 | 20 | os.chdir('test') 21 | 22 | if not os.path.exists('shrc'): 23 | raise Exception('no shrc found in directory %s' % testdir) 24 | 25 | try: 26 | f = open('shrc', 'r') 27 | lines = f.readlines() 28 | for line in lines: 29 | (key, _, value) = line.partition('=') 30 | os.environ[key.split()[1]] = value.rstrip().replace('"', '') 31 | finally: 32 | f.close() 33 | 34 | util.make('clean') 35 | util.make() 36 | 37 | os.environ['LD_LIBRARY_PATH'] = os.path.join(cwd, 'lib') # tcmalloc 38 | util.make('test') 39 | 40 | os.chdir(cwd) 41 | 42 | 43 | def setup(config): 44 | workdir = os.path.abspath(os.getcwd()) 45 | 46 | if not os.path.exists('typesan'): 47 | util.git.clone(typesan_repo) 48 | 49 | if not os.path.exists('llvm'): 50 | util.llvm.checkout(llvm_commit, clang_commit, compilerrt_commit) 51 | 52 | if not os.path.exists('llvm-build'): 53 | os.mkdir('llvm-build') 54 | 55 | # Apply TypeSan patches 56 | if config == configs[1]: 57 | llvm_patch = os.path.join(os.path.dirname(__file__), 'llvm.patch') 58 | clang_patch = os.path.join(os.path.dirname(__file__), 'clang.patch') 59 | compilerrt_patch = os.path.join(os.path.dirname(__file__), 'compiler-rt.patch') 60 | 61 | os.chdir('llvm') 62 | util.git.patch(llvm_patch) 63 | os.chdir(os.path.join(workdir, 'llvm/tools/clang')) 64 | util.git.patch(clang_patch) 65 | os.chdir(os.path.join(workdir, 'llvm/projects/compiler-rt')) 66 | util.git.patch(compilerrt_patch) 67 | os.chdir(workdir) 68 | 69 | util.llvm.compile(src_dir=os.path.abspath('llvm'), 70 | build_dir=os.path.abspath('llvm-build'), 71 | install_dir=os.getcwd()) 72 | 73 | if not glob.glob('gperftools*'): 74 | util.git.clone(gperftools_repo) 75 | os.chdir('gperftools') 76 | util.git.checkout(gperftools_commit) 77 | util.git.patch(os.path.join(os.path.dirname(__file__), 'GPERFTOOLS_SPEEDUP.patch')) 78 | 79 | if config == configs[1]: 80 | os.chdir(workdir) 81 | 82 | # Build metapagetable 83 | if not os.path.exists('gperftools-metalloc'): 84 | shutil.move('gperftools', 'gperftools-metalloc') 85 | 86 | if not os.path.exists('metapagetable'): 87 | config_fixedcompression = 'false' 88 | config_metadatabytes = 16 89 | config_deepmetadata = 'false' 90 | os.environ['METALLOC_OPTIONS'] = '-DFIXEDCOMPRESSION=%s -DMETADATABYTES=%d -DDEEPMETADATA=%s' % (config_fixedcompression, config_metadatabytes, config_deepmetadata) 91 | 92 | shutil.copytree(os.path.join('typesan', 'metapagetable'), 'metapagetable') 93 | os.chdir('metapagetable') 94 | util.make('config') 95 | util.make() 96 | os.chdir(workdir) 97 | 98 | # Apply TypeSan patches for gperftool 99 | os.chdir('gperftools-metalloc') 100 | util.git.patch(os.path.join(os.path.dirname(__file__), 'GPERFTOOLS_TYPESAN.patch')) 101 | 102 | util.run('autoreconf -fi') 103 | util.configure('--prefix=' + workdir) 104 | util.make() 105 | util.make('install') 106 | os.chdir(workdir) 107 | 108 | # Create spec config file 109 | print 'creating spec config file...' 110 | 111 | spec_cfg = '-'.join([command, config]) + '.cfg' 112 | 113 | if os.path.exists(spec_cfg): 114 | os.remove(spec_cfg) 115 | 116 | path = os.path.join('llvm-build', 'bin') 117 | 118 | cflags = [] 119 | extra_libs = [] 120 | if config == configs[1]: 121 | cflags = ['-fsanitize=typesan'] 122 | 123 | extra_libs.extend(['-ltcmalloc', '-lpthread', '-lunwind']) 124 | extra_libs.append('-L' + os.path.join(workdir, 'lib')) # tcmalloc 125 | 126 | cc = [os.path.abspath(os.path.join(path, 'clang'))] 127 | cc.extend(cflags) 128 | cxx = [os.path.abspath(os.path.join(path, 'clang++'))] 129 | cxx.extend(cflags) 130 | 131 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 132 | name='-'.join([command, config]), 133 | cc=' '.join(cc), cxx=' '.join(cxx), 134 | extra_libs=' '.join(extra_libs)) 135 | 136 | # create shrc for testing 137 | print('creating test directory...') 138 | 139 | if not os.path.exists('test'): 140 | testdir = os.path.join(os.path.dirname(__file__), 'test') 141 | shutil.copytree(testdir, os.path.join(workdir, 'test')) 142 | 143 | if os.path.exists('test/shrc'): 144 | os.remove('test/shrc') 145 | 146 | util.test.create_shrc( 147 | dir=os.path.abspath('test'), 148 | cc=' '.join(cc), cxx=' '.join(cxx), ld=' '.join(cxx), 149 | ldflags=' '.join(extra_libs) 150 | ) 151 | 152 | 153 | def clean(config): 154 | workdir = '-'.join([command, config]) 155 | if not os.path.exists(workdir): 156 | print 'nothing to clean' 157 | return 158 | 159 | shutil.rmtree(workdir) 160 | 161 | 162 | def run(config): 163 | if config.find('spec') > -1: 164 | print 'running ' + config + '...' 165 | spec_cfg = '-'.join([command, config]) + '.cfg' 166 | benchmarks = util.spec.cpp_benchmarks 167 | 168 | print 'running spec2006 cpu benchmark %s using %s...' % (', '.join(benchmarks), spec_cfg) 169 | 170 | os.environ['LD_LIBRARY_PATH'] = os.path.join(os.getcwd(), 'lib') # tcmalloc 171 | util.spec.runspec(config=os.path.abspath(spec_cfg), 172 | benchmarks=benchmarks) 173 | -------------------------------------------------------------------------------- /util/spec.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | 4 | 5 | default_cfg = """ 6 | monitor_wrapper = $SPEC_WRAPPER $command 7 | monitor_specrun_wrapper = $SPECRUN_WRAPPER $command 8 | ignore_errors = yes 9 | tune = base 10 | ext = $name 11 | output_format = asc, Screen 12 | output_root = $OUTPUT_ROOT 13 | reportable = 1 14 | teeout = yes 15 | teerunout = yes 16 | strict_rundir_verify = 0 17 | makeflags = -j$SPEC_J 18 | default=default=default=default: 19 | CC = $CC 20 | CXX = $CXX 21 | CLD = $CLD 22 | CXXLD = $CXXLD 23 | EXTRA_LIBS = $EXTRA_LIBS 24 | EXTRA_CXXLIBS = $EXTRA_CXXLIBS 25 | FC = echo 26 | 27 | default=base=default=default: 28 | COPTIMIZE = $OPT_LEVEL 29 | CXXOPTIMIZE = $OPT_LEVEL 30 | 31 | default=base=default=default: 32 | PORTABILITY = -DSPEC_CPU_LP64 33 | 34 | 400.perlbench=default=default=default: 35 | CPORTABILITY= -DSPEC_CPU_LINUX_X64 36 | EXTRA_CFLAGS= -std=gnu89 37 | 38 | 462.libquantum=default=default=default: 39 | CPORTABILITY = -DSPEC_CPU_LINUX 40 | 41 | 483.xalancbmk=default=default=default: 42 | CXXPORTABILITY = -DSPEC_CPU_LINUX 43 | 44 | 481.wrf=default=default=default: 45 | CPORTABILITY = -DSPEC_CPU_CASE_FLAG -DSPEC_CPU_LINUX 46 | """ 47 | 48 | 49 | int_benchmarks = ['400.perlbench', 50 | '401.bzip2', 51 | '403.gcc', 52 | '429.mcf', 53 | '445.gobmk', 54 | '456.hmmer', 55 | '458.sjeng', 56 | '462.libquantum', 57 | '464.h264ref', 58 | '471.omnetpp', 59 | '473.astar', 60 | '483.xalancbmk'] 61 | fp_benchmarks = ['433.milc', 62 | '444.namd', 63 | '447.dealII', 64 | '450.soplex', 65 | '453.povray', 66 | '470.lbm', 67 | '482.sphinx3'] 68 | cpp_benchmarks = ['471.omnetpp', 69 | '473.astar', 70 | '483.xalancbmk', 71 | '444.namd', 72 | '447.dealII', 73 | '450.soplex', 74 | '453.povray'] 75 | all_benchmarks = int_benchmarks + fp_benchmarks 76 | 77 | 78 | # SPEC CPU2006 support only 79 | def install(mountdir, installdir): 80 | if not os.path.exists(mountdir): 81 | raise Exception('mount dir does not exist') 82 | 83 | print 'installing SPEC CPU2006...' 84 | 85 | cwd = os.getcwd() 86 | os.mkdir(installdir) 87 | os.chdir(mountdir) 88 | 89 | subprocess.check_output(['./install.sh']) 90 | 91 | os.chdir(cwd) 92 | 93 | 94 | def create_config(dir, 95 | file, 96 | name, 97 | cc, 98 | cxx, 99 | cld='', 100 | cxxld='', 101 | opt_level='-O2 -fno-strict-aliasing', 102 | extra_libs='', 103 | extra_cxxlibs='', 104 | spec_wrapper='', 105 | cxxportability={}): 106 | if not os.path.exists(dir): 107 | raise Exception('config dir does not exist') 108 | 109 | if os.path.exists(file): 110 | raise Exception('config file already exists') 111 | 112 | if cld == '': 113 | cld = cc 114 | 115 | if cxxld == '': 116 | cxxld = cxx 117 | 118 | cfg = default_cfg 119 | cfg = cfg.replace('$name', name) 120 | cfg = cfg.replace('$CLD', cld) 121 | cfg = cfg.replace('$CC', cc) 122 | cfg = cfg.replace('$CXXLD', cxxld) 123 | cfg = cfg.replace('$CXX', cxx) 124 | cfg = cfg.replace('$SPEC_J', '4') # TODO 125 | cfg = cfg.replace('$OPT_LEVEL', opt_level) 126 | cfg = cfg.replace('$EXTRA_LIBS', extra_libs) 127 | cfg = cfg.replace('$EXTRA_CXXLIBS', extra_cxxlibs) 128 | cfg = cfg.replace('$SPEC_WRAPPER', spec_wrapper) 129 | cfg = cfg.replace('$SPECRUN_WRAPPER', '') 130 | cfg = cfg.replace('$OUTPUT_ROOT', dir) 131 | 132 | for bench in cxxportability.keys(): 133 | if not bench in all_benchmarks: 134 | raise Exception('%s not found' % bench) 135 | 136 | section_header = '%s=default=default=default:' % bench 137 | lines = cfg.split('\n') 138 | 139 | if section_header in lines: 140 | idx = lines.index(section_header) 141 | for i in range(idx + 1, len(lines) - 1): 142 | if lines[i].startswith('CXXPORTABILITY'): 143 | lines[i] += ' %s' % cxxportability[bench] 144 | cfg = '\n'.join(lines) 145 | break 146 | if lines[idx] == '': 147 | new_cxxport = ('CXXPORTABILITY = %s' % cxxportability[bench]) 148 | lines.insert(idx, new_cxxport + '\n') 149 | cfg = '\n'.join(lines) 150 | break 151 | else: 152 | new_section = [section_header] 153 | new_section.append('CXXPORTABILITY = %s' % cxxportability[bench]) 154 | cfg += '\n' + '\n'.join(new_section) + '\n' 155 | 156 | if cfg.replace('$command', '').find('$') > -1: 157 | raise Exception('config incomplete %s' % cfg) 158 | 159 | try: 160 | cfg_file = open(os.path.join(dir, file), 'w') 161 | cfg_file.write(cfg) 162 | finally: 163 | print os.path.abspath(cfg_file.name) 164 | cfg_file.close() 165 | 166 | 167 | def runspec(config, benchmarks, action='run', size='ref', iterations=3): 168 | 169 | assert os.path.exists(config), 'config does not exist' 170 | 171 | action = action.lower() 172 | 173 | assert action in ['build', 'clean', 'run'], 'invalid action' 174 | 175 | size = size.lower() 176 | 177 | assert size in ['test', 'train', 'ref'], 'invalid size' 178 | 179 | pathspec = os.getenv('SPEC') 180 | if not pathspec: 181 | raise Exception('SPEC not found') 182 | if not os.path.exists(pathspec): 183 | raise Exception('SPEC dir does not exist: ' + pathspec) 184 | 185 | os.chdir(pathspec) 186 | 187 | cmd = ['runspec'] 188 | cmd.extend(['--config', config]) 189 | cmd.extend(['--action', action]) 190 | cmd.extend(['--size', size]) 191 | cmd.extend(['--iterations', str(iterations)]) 192 | cmd.extend(['--ignore_errors', '--loose']) 193 | cmd.extend(benchmarks) 194 | 195 | print ' '.join(cmd) 196 | p = subprocess.Popen(' '.join(cmd), shell=True) 197 | p.wait() 198 | 199 | -------------------------------------------------------------------------------- /CPU2006.patch: -------------------------------------------------------------------------------- 1 | diff --git a/400.perlbench/src/perlio.c b/400.perlbench/src/perlio.c 2 | index c38fbec..677c815 100644 3 | --- a/400.perlbench/src/perlio.c 4 | +++ b/400.perlbench/src/perlio.c 5 | @@ -748,7 +748,11 @@ PerlIO_find_layer(pTHX_ const char *name, STRLEN len, int load) 6 | len = strlen(name); 7 | for (i = 0; i < PL_known_layers->cur; i++) { 8 | PerlIO_funcs *f = PL_known_layers->array[i].funcs; 9 | +#ifdef PATCH_PERLBENCH_OVERFLOW 10 | + if (!strcmp(f->name, name) && f->name[len] == 0) { 11 | +#else 12 | if (memEQ(f->name, name, len) && f->name[len] == 0) { 13 | +#endif 14 | PerlIO_debug("%.*s => %p\n", (int) len, name, (void*)f); 15 | return f; 16 | } 17 | diff --git a/447.dealII/src/include/grid/tria_accessor.h b/447.dealII/src/include/grid/tria_accessor.h 18 | index ea24b8c..dfb6193 100644 19 | --- a/447.dealII/src/include/grid/tria_accessor.h 20 | +++ b/447.dealII/src/include/grid/tria_accessor.h 21 | @@ -36,11 +36,13 @@ template class TriaObjectAccessor<2, dim>; 22 | template class TriaObjectAccessor<3, dim>; 23 | 24 | 25 | +#ifndef NO_DEALII_STD_PAIR 26 | namespace std 27 | { 28 | template 29 | struct pair; 30 | } 31 | +#endif 32 | 33 | // note: the file tria_accessor.templates.h is included at the end of 34 | // this file. this includes a lot of templates. originally, this was 35 | diff --git a/450.soplex/src/idlist.h b/450.soplex/src/idlist.h 36 | index 728b996..d5d8fdf 100644 37 | --- a/450.soplex/src/idlist.h 38 | +++ b/450.soplex/src/idlist.h 39 | @@ -269,6 +269,15 @@ public: 40 | } 41 | //@} 42 | 43 | +#ifdef SOPLEX_DANGSAN_MASK 44 | + static T *moveptr(T *ptr, ptrdiff_t delta) 45 | + { 46 | + unsigned long mask = 0x7fffffffffffffffUL; 47 | + unsigned long newptr = reinterpret_cast(ptr) + delta; 48 | + unsigned long maskedptr = newptr & mask; 49 | + return reinterpret_cast(maskedptr); 50 | + } 51 | +#endif 52 | 53 | /**@name Miscellaneous */ 54 | //@{ 55 | @@ -285,8 +294,12 @@ public: 56 | IsList::move(delta); 57 | for (elem = last(); elem; elem = prev(elem)) 58 | if (elem != first()) 59 | +#ifdef SOPLEX_DANGSAN_MASK 60 | + elem->prev() = moveptr(elem->prev(), delta); 61 | +#else 62 | elem->prev() = reinterpret_cast( 63 | reinterpret_cast(elem->prev()) + delta); 64 | +#endif 65 | } 66 | } 67 | 68 | diff --git a/450.soplex/src/islist.h b/450.soplex/src/islist.h 69 | index d8d2485..9ce4896 100644 70 | --- a/450.soplex/src/islist.h 71 | +++ b/450.soplex/src/islist.h 72 | @@ -340,6 +340,16 @@ public: 73 | } 74 | //@} 75 | 76 | +#ifdef SOPLEX_DANGSAN_MASK 77 | + static T *moveptr(T *ptr, ptrdiff_t delta) 78 | + { 79 | + unsigned long mask = 0x7fffffffffffffffUL; 80 | + unsigned long newptr = reinterpret_cast(ptr) + delta; 81 | + unsigned long maskedptr = newptr & mask; 82 | + return reinterpret_cast(maskedptr); 83 | + } 84 | +#endif 85 | + 86 | /**@name Miscellaneous */ 87 | //@{ 88 | /// adjusts list pointers to a new memory address. 89 | @@ -356,11 +366,20 @@ public: 90 | if (the_first) 91 | { 92 | T* elem; 93 | +#ifdef SOPLEX_DANGSAN_MASK 94 | + the_last = moveptr(the_last, delta); 95 | + the_first = moveptr(the_first, delta); 96 | +#else 97 | the_last = reinterpret_cast(reinterpret_cast(the_last) + delta); 98 | the_first = reinterpret_cast(reinterpret_cast(the_first) + delta); 99 | +#endif 100 | for (elem = first(); elem; elem = next(elem)) 101 | if (elem != last()) 102 | +#ifdef SOPLEX_DANGSAN_MASK 103 | + elem->next() = moveptr(elem->next(), delta); 104 | +#else 105 | elem->next() = reinterpret_cast(reinterpret_cast(elem->next()) + delta); 106 | +#endif 107 | } 108 | } 109 | 110 | diff --git a/450.soplex/src/svset.cc b/450.soplex/src/svset.cc 111 | index 3ea9872..07bda5f 100644 112 | --- a/450.soplex/src/svset.cc 113 | +++ b/450.soplex/src/svset.cc 114 | @@ -254,6 +254,16 @@ void SVSet::reMax(int newmax) 115 | list.move(set.reMax(newmax)); 116 | } 117 | 118 | +#ifdef SOPLEX_DANGSAN_MASK 119 | +static SVector::Element *moveptr(void *ptr, ptrdiff_t delta) 120 | +{ 121 | + unsigned long mask = 0x7fffffffffffffffUL; 122 | + unsigned long newptr = reinterpret_cast(ptr) + delta; 123 | + unsigned long maskedptr = newptr & mask; 124 | + return reinterpret_cast(maskedptr); 125 | +} 126 | +#endif 127 | + 128 | void SVSet::memRemax(int newmax) 129 | { 130 | ptrdiff_t delta = DataArray < SVector::Element > ::reMax(newmax); 131 | @@ -262,7 +272,11 @@ void SVSet::memRemax(int newmax) 132 | { 133 | for (DLPSV* ps = list.first(); ps; ps = list.next(ps)) 134 | { 135 | +#ifdef SOPLEX_DANGSAN_MASK 136 | + SVector::Element * info = moveptr(ps->mem(), delta); 137 | +#else 138 | SVector::Element * info = reinterpret_cast(reinterpret_cast(ps->mem()) + delta); 139 | +#endif 140 | int sz = info->idx; 141 | int l_max = int( info->val ); 142 | assert(l_max >= sz ); 143 | diff --git a/464.h264ref/src/mv-search.c b/464.h264ref/src/mv-search.c 144 | index 504d8c4..5eea29b 100644 145 | --- a/464.h264ref/src/mv-search.c 146 | +++ b/464.h264ref/src/mv-search.c 147 | @@ -1016,7 +1016,12 @@ FastFullPelBlockMotionSearch (pel_t** orig_pic, // <-- not used 148 | int 149 | SATD (int* diff, int use_hadamard) 150 | { 151 | +#ifdef PATCH_H264REF_OVERFLOW 152 | + /* https://www.spec.org/cpu2006/Docs/faq.html#Run.05 */ 153 | + int k, satd = 0, m[16], dd, d[16+1]; 154 | +#else 155 | int k, satd = 0, m[16], dd, d[16]; 156 | +#endif 157 | 158 | if (use_hadamard) 159 | { 160 | diff --git a/471.omnetpp/src/libs/cmdenv/heap.cc b/471.omnetpp/src/libs/cmdenv/heap.cc 161 | index 2c92a2c..510efed 100644 162 | --- a/471.omnetpp/src/libs/cmdenv/heap.cc 163 | +++ b/471.omnetpp/src/libs/cmdenv/heap.cc 164 | @@ -295,6 +295,7 @@ void dispheap() 165 | } 166 | #endif 167 | 168 | +#ifndef NO_OMNETPP_OPERATOR_NEW // Some sanitizers (e.g., ASan) can not link if there is a use-defined operator new 169 | void *operator new(size_t m) 170 | { 171 | #ifdef HEAPCHECK 172 | @@ -400,3 +401,4 @@ void operator delete(void *p) 173 | if(id==breakat) brk("DELETE"); 174 | #endif 175 | } 176 | +#endif // NO_OMNETPP_OPERATOR_NEW 177 | -------------------------------------------------------------------------------- /hexvasan/clang.patch: -------------------------------------------------------------------------------- 1 | diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def 2 | index c81273e..cd8d43c 100644 3 | --- a/include/clang/Basic/Sanitizers.def 4 | +++ b/include/clang/Basic/Sanitizers.def 5 | @@ -75,6 +75,11 @@ SANITIZER("unreachable", Unreachable) 6 | SANITIZER("vla-bound", VLABound) 7 | SANITIZER("vptr", Vptr) 8 | 9 | +SANITIZER("vasan", VASAN) 10 | +SANITIZER("vasan-backtrace", VASANBacktrace) 11 | +SANITIZER("vasan-stats", VASANStats) 12 | +SANITIZER("vasan-libc", VASANLibc) 13 | + 14 | // IntegerSanitizer 15 | SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow) 16 | 17 | @@ -102,7 +107,7 @@ SANITIZER_GROUP("undefined", Undefined, 18 | FloatDivideByZero | IntegerDivideByZero | NonnullAttribute | 19 | Null | ObjectSize | Return | ReturnsNonnullAttribute | 20 | Shift | SignedIntegerOverflow | Unreachable | VLABound | 21 | - Function | Vptr) 22 | + Function | Vptr | VASAN | VASANBacktrace | VASANStats | VASANLibc) 23 | 24 | // -fsanitize=undefined-trap is an alias for -fsanitize=undefined. 25 | SANITIZER_GROUP("undefined-trap", UndefinedTrap, Undefined) 26 | diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h 27 | index 7b293e0..262d44d 100644 28 | --- a/include/clang/Driver/SanitizerArgs.h 29 | +++ b/include/clang/Driver/SanitizerArgs.h 30 | @@ -47,6 +47,10 @@ class SanitizerArgs { 31 | bool needsSharedAsanRt() const { return AsanSharedRuntime; } 32 | bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } 33 | bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); } 34 | + bool needsVASANRt() const { return Sanitizers.has(SanitizerKind::VASAN); } 35 | + bool needsVASANStatsRt() const { return Sanitizers.has(SanitizerKind::VASANStats); } 36 | + bool needsVASANBacktraceRt() const { return Sanitizers.has(SanitizerKind::VASANBacktrace); } 37 | + bool needsVASANLibcRt() const { return Sanitizers.has(SanitizerKind::VASANLibc); } 38 | bool needsLsanRt() const { 39 | return Sanitizers.has(SanitizerKind::Leak) && 40 | !Sanitizers.has(SanitizerKind::Address); 41 | diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp 42 | index 165b6dd..ff185e3 100644 43 | --- a/lib/CodeGen/BackendUtil.cpp 44 | +++ b/lib/CodeGen/BackendUtil.cpp 45 | @@ -163,6 +163,15 @@ static void addBoundsCheckingPass(const PassManagerBuilder &Builder, 46 | PM.add(createBoundsCheckingPass()); 47 | } 48 | 49 | +static void addVASANPass(const PassManagerBuilder &Builder, 50 | + PassManagerBase &PM) { 51 | + PM.add(createVASANPass()); 52 | +} 53 | +static void addVASANCallerPass(const PassManagerBuilder &Builder, 54 | + PassManagerBase &PM) { 55 | + PM.add(createVASANCallerPass()); 56 | +} 57 | + 58 | static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, 59 | legacy::PassManagerBase &PM) { 60 | const PassManagerBuilderWrapper &BuilderWrapper = 61 | @@ -179,6 +188,8 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, 62 | PM.add(createSanitizerCoverageModulePass(Opts)); 63 | } 64 | 65 | + 66 | + 67 | static void addAddressSanitizerPasses(const PassManagerBuilder &Builder, 68 | legacy::PassManagerBase &PM) { 69 | const PassManagerBuilderWrapper &BuilderWrapper = 70 | @@ -413,6 +424,21 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, 71 | addDataFlowSanitizerPass); 72 | } 73 | 74 | + if (LangOpts.Sanitize.has(SanitizerKind::VASANBacktrace) || 75 | + LangOpts.Sanitize.has(SanitizerKind::VASAN) || 76 | + LangOpts.Sanitize.has(SanitizerKind::VASANLibc) || 77 | + LangOpts.Sanitize.has(SanitizerKind::VASANStats)) { 78 | + PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, 79 | + addVASANPass); 80 | + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, 81 | + addVASANPass); 82 | + PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, 83 | + addVASANCallerPass); 84 | + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, 85 | + addVASANCallerPass); 86 | + 87 | + } 88 | + 89 | if (LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency)) { 90 | PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, 91 | addEfficiencySanitizerPass); 92 | diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp 93 | index 31d4360..921e5dc 100644 94 | --- a/lib/Driver/Tools.cpp 95 | +++ b/lib/Driver/Tools.cpp 96 | @@ -3109,6 +3109,16 @@ static void linkSanitizerRuntimeDeps(const ToolChain &TC, 97 | // There's no libdl on FreeBSD. 98 | if (TC.getTriple().getOS() != llvm::Triple::FreeBSD) 99 | CmdArgs.push_back("-ldl"); 100 | + else if (TC.getSanitizerArgs().needsVASANLibcRt()) { 101 | + CmdArgs.push_back("-lexecinfo"); 102 | + CmdArgs.push_back("-lelf"); 103 | + } 104 | + else if (TC.getSanitizerArgs().needsVASANRt() || 105 | + TC.getSanitizerArgs().needsVASANBacktraceRt() || 106 | + TC.getSanitizerArgs().needsVASANStatsRt()) 107 | + { 108 | + CmdArgs.push_back("-lstdc++"); 109 | + } 110 | } 111 | 112 | static void 113 | @@ -3127,6 +3137,12 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, 114 | if (SanArgs.needsStatsRt()) 115 | StaticRuntimes.push_back("stats_client"); 116 | 117 | + // Only link into shared libs if someone passes -fsanitize=vasan-libc 118 | + if (SanArgs.needsVASANLibcRt()) 119 | + StaticRuntimes.push_back("vasan_libc"); 120 | + 121 | + 122 | + 123 | // Collect static runtimes. 124 | if (Args.hasArg(options::OPT_shared) || TC.getTriple().isAndroid()) { 125 | // Don't link static runtimes into DSOs or if compiling for Android. 126 | @@ -3173,6 +3189,14 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, 127 | NonWholeStaticRuntimes.push_back("stats"); 128 | RequiredSymbols.push_back("__sanitizer_stats_register"); 129 | } 130 | + 131 | + if (SanArgs.needsVASANBacktraceRt()) 132 | + StaticRuntimes.push_back("vasan_backtrace"); 133 | + else if (SanArgs.needsVASANStatsRt()) 134 | + StaticRuntimes.push_back("vasan_stats"); 135 | + else if (SanArgs.needsVASANRt()) 136 | + StaticRuntimes.push_back("vasan"); 137 | + 138 | if (SanArgs.needsEsanRt()) 139 | StaticRuntimes.push_back("esan"); 140 | } 141 | -------------------------------------------------------------------------------- /lowfat/lowfat.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import subprocess 4 | import util 5 | 6 | 7 | command = 'lowfat' 8 | configs = ['baseline-spec', 'spec', 'spec-debug', 'spec-noabort'] 9 | repo = 'https://github.com/GJDuck/LowFat.git' 10 | llvmver = '4.0.0' 11 | 12 | 13 | def test(config): 14 | return True 15 | 16 | 17 | def setup(config): 18 | workdir = os.path.abspath(os.getcwd()) 19 | configdir = os.path.join(os.path.dirname(__file__), 'config') 20 | INSTRUMENTATION_PATH = os.path.abspath('llvm/lib/Transforms/Instrumentation') 21 | 22 | if not os.path.exists('llvm'): 23 | util.llvm.download(llvmver, os.getcwd()) 24 | 25 | # Apply patches common to both baseline and LowFat 26 | bug81066_patch = os.path.join(os.path.dirname(__file__), 'bug81066.patch') 27 | os.chdir('llvm/projects/compiler-rt') 28 | util.patch(os.path.abspath(bug81066_patch), '-p0') 29 | os.chdir(workdir) 30 | 31 | if not os.path.exists('llvm-4.0.0') and not os.path.exists('llvm-lowfat'): 32 | os.mkdir('llvm-4.0.0') 33 | util.llvm.compile(src_dir=os.path.abspath('llvm'), 34 | build_dir=os.path.abspath('llvm-4.0.0'), 35 | install_dir=workdir) 36 | 37 | if config != configs[0]: 38 | os.environ['CC'] = os.path.abspath('llvm-4.0.0/bin/clang') 39 | os.environ['CXX'] = os.path.abspath('llvm-4.0.0/bin/clang++') 40 | 41 | if not os.path.exists('llvm-lowfat'): 42 | print 'patching llvm/clang/compiler-rt version ' + llvmver + '...' 43 | 44 | llvm_patch = os.path.join(os.path.dirname(__file__), 'llvm.patch') 45 | clang_patch = os.path.join(os.path.dirname(__file__), 'clang.patch') 46 | compilerrt_patch = os.path.join(os.path.dirname(__file__), 'compiler-rt.patch') 47 | 48 | legacy_compilerrt_patch = os.path.join(os.path.dirname(__file__), 'legacy_compiler-rt.patch') 49 | modern_compilerrt_patch = os.path.join(os.path.dirname(__file__), 'modern_compiler-rt.patch') 50 | 51 | os.chdir('llvm') 52 | util.patch(os.path.abspath(llvm_patch)) 53 | os.chdir(workdir) 54 | 55 | os.chdir('llvm/tools/clang') 56 | util.patch(os.path.abspath(clang_patch)) 57 | os.chdir(workdir) 58 | 59 | os.chdir('llvm/projects/compiler-rt') 60 | util.patch(os.path.abspath(compilerrt_patch)) 61 | 62 | cpuinfo = util.stdout(['cat', '/proc/cpuinfo']).strip().split('\n') 63 | 64 | legacy = False 65 | 66 | if not [s for s in cpuinfo if ' bmi1' in s]: 67 | legacy = True 68 | 69 | if not [s for s in cpuinfo if ' bmi2' in s]: 70 | legacy = True 71 | 72 | if not [s for s in cpuinfo if ' abm' in s]: 73 | legacy = True 74 | 75 | if legacy: 76 | util.patch(os.path.abspath(legacy_compilerrt_patch)) 77 | else: 78 | util.patch(os.path.abspath(modern_compilerrt_patch)) 79 | 80 | os.chdir(workdir) 81 | 82 | print 'building the LowFat config builder...' 83 | 84 | CONFIG = 'sizes.cfg 32' 85 | os.chdir(os.path.join(os.path.dirname(__file__), 'config')) 86 | util.make() 87 | util.run('./lowfat-config ' + CONFIG) 88 | util.make('lowfat-check-config') 89 | util.run('./lowfat-check-config') 90 | os.chdir(workdir) 91 | 92 | print 'copying the LowFat config files...' 93 | 94 | RUNTIME_PATH = os.path.abspath('llvm/projects/compiler-rt/lib/lowfat') 95 | shutil.copy(os.path.join(configdir, 'lowfat_config.h'), RUNTIME_PATH) 96 | shutil.copy(os.path.join(configdir, 'lowfat_config.c'), RUNTIME_PATH) 97 | 98 | CLANGLIB_PATH = os.path.abspath('llvm/tools/clang/lib/Basic') 99 | shutil.copy(os.path.join(RUNTIME_PATH, 'lowfat_config.c'), 100 | os.path.join(INSTRUMENTATION_PATH, 'lowfat_config.inc')) 101 | shutil.copy(os.path.join(RUNTIME_PATH, 'lowfat_config.h'), 102 | os.path.join(INSTRUMENTATION_PATH, 'lowfat_config.h')) 103 | shutil.copy(os.path.join(RUNTIME_PATH, 'lowfat_config.h'), 104 | os.path.join(CLANGLIB_PATH, 'lowfat_config.h')) 105 | shutil.copy(os.path.join(RUNTIME_PATH, 'lowfat.h'), 106 | os.path.join(INSTRUMENTATION_PATH, 'lowfat.h')) 107 | 108 | os.mkdir('llvm-lowfat') 109 | 110 | util.llvm.compile(src_dir=os.path.abspath('llvm'), 111 | build_dir=os.path.abspath('llvm-lowfat'), 112 | install_dir=workdir) 113 | 114 | os.chdir('llvm-lowfat') 115 | 116 | if not os.path.exists('lib/LowFat'): 117 | if not os.path.exists('lib'): 118 | os.mkdir('lib') 119 | os.mkdir('lib/LowFat') 120 | shutil.copy(os.path.join(configdir, 'lowfat.ld'), 121 | os.path.join('lib/LowFat', 'lowfat.ld')) 122 | 123 | if not os.path.exists('bin/lowfat-ptr-info'): 124 | os.chdir(configdir) 125 | util.make('lowfat-ptr-info') 126 | shutil.copy('lowfat-ptr-info', os.path.join(workdir, 'llvm-lowfat', 'bin')) 127 | 128 | os.chdir(workdir) 129 | 130 | if not os.path.exists('LowFat.so'): 131 | clangxx = os.path.join('llvm-4.0.0', 'bin', 'clang++') 132 | llvm_config = os.path.join('llvm-4.0.0', 'bin', 'llvm-config') 133 | 134 | cxxflags = util.stdout([llvm_config, '--cxxflags']).rstrip('\n') 135 | includedir = util.stdout([llvm_config, '--includedir']).rstrip('\n') 136 | cmd = ' '.join([clangxx, '-DLOWFAT_PLUGIN', 137 | os.path.join(INSTRUMENTATION_PATH, 'LowFat.cpp'), 138 | '-c -Wall -O2', 139 | '-I' + INSTRUMENTATION_PATH, 140 | '-o LowFat.o', 141 | cxxflags, includedir]) 142 | util.run(cmd) 143 | 144 | ldflags = util.stdout([llvm_config, '--ldflags']).rstrip('\n') 145 | cmd = ' '.join([clangxx, '-shared -rdynamic -o LowFat.so LowFat.o', ldflags]) 146 | util.run(cmd) 147 | 148 | os.chdir(workdir) 149 | 150 | # Create spec config file 151 | print 'creating spec config file...' 152 | 153 | spec_cfg = '-'.join([command, config]) + '.cfg' 154 | 155 | if os.path.exists(spec_cfg): 156 | os.remove(spec_cfg) 157 | 158 | if config == configs[0]: 159 | path = os.path.join('llvm-4.0.0', 'bin') 160 | cflags = [] 161 | else: 162 | path = os.path.join('llvm-lowfat', 'bin') 163 | cflags = ['-fsanitize=lowfat'] 164 | blacklist = os.path.join(os.path.dirname(__file__), 'blacklist.txt') 165 | cflags.extend(['-mllvm', '-lowfat-no-check-blacklist=%s' % blacklist]) 166 | 167 | cflags.append('-DPATCH_PERLBENCH_OVERFLOW') 168 | cflags.append('-DPATCH_H264REF_OVERFLOW') 169 | 170 | if config == configs[2]: 171 | cflags.append('-g') 172 | cflags.append('-fno-inline-functions') 173 | 174 | if config == configs[3]: 175 | cflags.append('-mllvm -lowfat-no-abort') 176 | 177 | cc = [os.path.abspath(os.path.join(path, 'clang'))] 178 | cc.extend(cflags) 179 | cxx = [os.path.abspath(os.path.join(path, 'clang++'))] 180 | cxx.extend(cflags) 181 | 182 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 183 | name='-'.join([command, config]), 184 | cc=' '.join(cc), cxx=' '.join(cxx)) 185 | 186 | 187 | def clean(config): 188 | workdir = '-'.join(['lowfat', config]) 189 | if not os.path.exists(workdir): 190 | print 'nothing to clean' 191 | return 192 | 193 | shutil.rmtree(workdir) 194 | 195 | 196 | def run(config): 197 | if config.find('spec') > -1: 198 | print 'running ' + config + '...' 199 | spec_cfg = '-'.join([command, config]) + '.cfg' 200 | benchmarks = util.spec.all_benchmarks 201 | 202 | if config == configs[2] or config == configs[3]: 203 | benchmarks = ['400', '403', '464', '444', '450'] 204 | 205 | print 'running spec2006 cpu benchmark %s using %s...' % (', '.join(benchmarks), spec_cfg) 206 | 207 | util.spec.runspec(config=os.path.abspath(spec_cfg), 208 | benchmarks=benchmarks) 209 | -------------------------------------------------------------------------------- /util/llvm.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | import subprocess 4 | import git 5 | import svn 6 | 7 | 8 | MAX_CPU_CORES = 10 9 | 10 | 11 | llvm_url_format = 'http://releases.llvm.org/VERSION/llvm-VERSION.EXT' 12 | clang_url_format = 'http://releases.llvm.org/VERSION/cfe-VERSION.EXT' 13 | compilerrt_url_format = 'http://releases.llvm.org/VERSION/compiler-rt-VERSION.EXT' 14 | libcxx_url_format = 'http://releases.llvm.org/6.0.0/libcxx-VERSION.EXT' 15 | libcxxabi_url_format = 'http://releases.llvm.org/6.0.0/libcxxabi-VERSION.EXT' 16 | 17 | llvm_git_repo = 'https://git.llvm.org/git/llvm.git' 18 | clang_git_repo = 'https://git.llvm.org/git/clang.git' 19 | compilerrt_git_repo = 'https://git.llvm.org/git/compiler-rt.git' 20 | 21 | llvm_svn_repo = 'http://llvm.org/svn/llvm-project/llvm/trunk' 22 | clang_svn_repo = 'http://llvm.org/svn/llvm-project/cfe/trunk' 23 | compilerrt_svn_repo = 'http://llvm.org/svn/llvm-project/compiler-rt/trunk' 24 | 25 | 26 | def checkout(llvm_commit, clang_commit, compilerrt_commit): 27 | cwd = os.path.abspath(os.getcwd()) 28 | 29 | if not os.path.exists('llvm'): 30 | git.clone(llvm_git_repo, ['-n']) 31 | os.chdir('llvm') 32 | git.checkout(llvm_commit) 33 | 34 | os.chdir(os.path.join(cwd, 'llvm', 'tools')) 35 | if not os.path.exists('clang'): 36 | git.clone(clang_git_repo, ['-n']) 37 | os.chdir('clang') 38 | git.checkout(clang_commit) 39 | 40 | os.chdir(os.path.join(cwd, 'llvm', 'projects')) 41 | if not os.path.exists('compiler-rt'): 42 | git.clone(compilerrt_git_repo, ['-n']) 43 | os.chdir('compiler-rt') 44 | git.checkout(compilerrt_commit) 45 | 46 | os.chdir(cwd) 47 | 48 | 49 | def checkout_svn(llvm_rev=''): 50 | svn.checkout(llvm_rev, llvm_svn_repo, 'llvm-svn') 51 | svn.checkout(llvm_rev, clang_svn_repo, os.path.join('llvm-svn', 'tools', 'clang')) 52 | svn.checkout(llvm_rev, compilerrt_svn_repo, os.path.join('llvm-svn', 'projects', 'compiler-rt')) 53 | 54 | 55 | def download(version, dir): 56 | if not os.path.exists(dir): 57 | raise Exception('target directory does not exist') 58 | 59 | ver_major = int(version.split('.')[0]) 60 | ver_minor = int(version.split('.')[1]) 61 | 62 | cwd = os.getcwd() 63 | os.chdir(dir) 64 | 65 | file_ext = 'src.tar.xz' 66 | if ver_major <= 3 and ver_minor <= 5: 67 | file_ext = 'src.tar.gz' 68 | 69 | print 'downloading llvm ' + version + '...' 70 | url = llvm_url_format.replace('VERSION', version).replace('EXT', file_ext) 71 | tar_file = '.'.join(['llvm-' + version, file_ext]) 72 | if not os.path.exists(tar_file): 73 | subprocess.check_output(['wget', url]) 74 | if not os.path.exists('llvm'): 75 | subprocess.check_output(['tar', '-xvf', tar_file]) 76 | if ver_major <= 3 and ver_minor <= 5: 77 | shutil.move('llvm-' + version, 'llvm-' + version + '.src') 78 | shutil.move('llvm-' + version + '.src', 'llvm') 79 | 80 | print 'downloading clang ' + version + '...' 81 | url = clang_url_format.replace('VERSION', version).replace('EXT', file_ext) 82 | tar_file = '.'.join(['cfe-' + version, file_ext]) 83 | if ver_major <= 3 and ver_minor <= 5: 84 | url = url.replace('cfe', 'clang') 85 | tar_file = '.'.join(['clang-' + version, file_ext]) 86 | if not os.path.exists(tar_file): 87 | subprocess.check_output(['wget', url]) 88 | if not os.path.exists(os.path.join('llvm', 'tools', 'clang')): 89 | subprocess.check_output(['tar', '-xvf', tar_file]) 90 | if ver_major <= 3 and ver_minor <= 5: 91 | shutil.move('clang-' + version, 'cfe-' + version + '.src') 92 | shutil.move('cfe-' + version + '.src', os.path.join('llvm', 'tools', 'clang')) 93 | 94 | print 'downloading compiler-rt ' + version + '...' 95 | url = compilerrt_url_format.replace('VERSION', version).replace('EXT', file_ext) 96 | tar_file = '.'.join(['compiler-rt-' + version, file_ext]) 97 | if not os.path.exists(tar_file): 98 | subprocess.check_output(['wget', url]) 99 | if not os.path.exists(os.path.join('llvm', 'projects', 'compiler-rt')): 100 | subprocess.check_output(['tar', '-xvf', tar_file]) 101 | if ver_major <= 3 and ver_minor <= 5: 102 | shutil.move('compiler-rt-' + version, 'compiler-rt-' + version + '.src') 103 | shutil.move('compiler-rt-' + version + '.src', os.path.join('llvm', 'projects', 'compiler-rt')) 104 | 105 | os.chdir(cwd) 106 | 107 | 108 | def download_libcxx(version, libcxx, libcxxabi): 109 | if not os.path.exists('llvm'): 110 | raise Exception('llvm does not exist') 111 | 112 | ver_major = int(version.split('.')[0]) 113 | ver_minor = int(version.split('.')[1]) 114 | 115 | cwd = os.path.abspath(os.getcwd()) 116 | 117 | file_ext = 'src.tar.xz' 118 | if ver_major <= 3 and ver_minor <= 5: 119 | file_ext = 'src.tar.gz' 120 | 121 | if libcxx: 122 | print 'downloading libcxx ' + version + '...' 123 | url = libcxx_url_format.replace('VERSION', version).replace('EXT', file_ext) 124 | tar_file = '.'.join(['libcxx-' + version, file_ext]) 125 | if not os.path.exists(tar_file): 126 | subprocess.check_output(['wget', url]) 127 | if not os.path.exists(os.path.join('llvm', 'projects', 'libcxx')): 128 | subprocess.check_output(['tar', '-xvf', tar_file]) 129 | if ver_major <= 3 and ver_minor <= 5: 130 | shutil.move('libcxx-' + version, 'libcxx-' + version + '.src') 131 | shutil.move('libcxx-' + version + '.src', os.path.join('llvm', 'projects', 'libcxx')) 132 | 133 | if libcxxabi: 134 | print 'downloading libcxxabi ' + version + '...' 135 | url = libcxxabi_url_format.replace('VERSION', version).replace('EXT', file_ext) 136 | tar_file = '.'.join(['libcxxabi-' + version, file_ext]) 137 | if not os.path.exists(tar_file): 138 | subprocess.check_output(['wget', url]) 139 | if not os.path.exists(os.path.join('llvm', 'projects', 'libcxxabi')): 140 | subprocess.check_output(['tar', '-xvf', tar_file]) 141 | if ver_major <= 3 and ver_minor <= 5: 142 | shutil.move('libcxxabi-' + version, 'libcxxabi-' + version + '.src') 143 | shutil.move('libcxxabi-' + version + '.src', os.path.join('llvm', 'projects', 'libcxxabi')) 144 | 145 | os.chdir(cwd) 146 | 147 | 148 | def compile(src_dir, build_dir, install_dir, options=[], ninja=True): 149 | if not build_dir or not os.path.exists(build_dir): 150 | raise Exception('build dir does not exist') 151 | 152 | cwd = os.getcwd() 153 | os.chdir(build_dir) 154 | 155 | if not src_dir or not os.path.exists(src_dir): 156 | raise Exception('llvm does not exist') 157 | 158 | if not install_dir or not os.path.exists(install_dir): 159 | raise Exception('install dir does not exist') 160 | 161 | print 'compiling llvm...' 162 | 163 | gen_build_cmd = ['cmake'] 164 | if ninja: 165 | gen_build_cmd.append('-GNinja') 166 | gen_build_cmd.append(src_dir) 167 | gen_build_cmd.append('-DCMAKE_INSTALL_PREFIX=' + install_dir) 168 | gen_build_cmd.append('-DCMAKE_BUILD_TYPE=Release') 169 | gen_build_cmd.append('-DLLVM_TARGETS_TO_BUILD=X86') 170 | gen_build_cmd.extend(options) 171 | p = subprocess.Popen(' '.join(gen_build_cmd), shell=True) 172 | p.wait() 173 | 174 | build_cmd = [] 175 | if ninja: 176 | build_cmd.append('ninja -j%d' % MAX_CPU_CORES) 177 | else: 178 | build_cmd.append('make -j%d' % MAX_CPU_CORES) 179 | 180 | p = subprocess.Popen(' '.join(build_cmd), shell=True) 181 | p.wait() 182 | 183 | os.chdir(cwd) 184 | 185 | 186 | def compile_libcxx(src_dir, build_dir, install_dir, options=[], ninja=True): 187 | if not build_dir or not os.path.exists(build_dir): 188 | raise Exception('build dir does not exist') 189 | 190 | cwd = os.getcwd() 191 | os.chdir(build_dir) 192 | 193 | if not src_dir or not os.path.exists(src_dir): 194 | raise Exception('llvm does not exist') 195 | 196 | if not install_dir or not os.path.exists(install_dir): 197 | raise Exception('install dir does not exist') 198 | 199 | print 'compiling libcxx/libcxxabi...' 200 | 201 | gen_build_cmd = ['cmake'] 202 | if ninja: 203 | gen_build_cmd.append('-GNinja') 204 | gen_build_cmd.append(src_dir) 205 | gen_build_cmd.append('-DCMAKE_INSTALL_PREFIX=' + install_dir) 206 | gen_build_cmd.append('-DCMAKE_BUILD_TYPE=Release') 207 | gen_build_cmd.extend(options) 208 | p = subprocess.Popen(' '.join(gen_build_cmd), shell=True) 209 | p.wait() 210 | 211 | build_cmd = [] 212 | if ninja: 213 | build_cmd.append('ninja cxx -j%d' % MAX_CPU_CORES) 214 | else: 215 | build_cmd.append('make cxx -j%d' % MAX_CPU_CORES) 216 | 217 | p = subprocess.Popen(' '.join(build_cmd), shell=True) 218 | p.wait() 219 | 220 | os.chdir(cwd) 221 | 222 | 223 | def install(build_dir): 224 | cwd = os.getcwd() 225 | os.chdir(build_dir) 226 | 227 | build_cmd = ['ninja', 'install'] 228 | p = subprocess.Popen(' '.join(build_cmd), shell=True) 229 | p.wait() 230 | 231 | os.chdir(cwd) 232 | -------------------------------------------------------------------------------- /dangsan/dangsan.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import shutil 4 | import subprocess 5 | import util 6 | 7 | 8 | command = 'dangsan' 9 | configs = ['baseline-spec', 'spec', 'spec-debug'] 10 | dangsan_repo = 'https://github.com/vusec/dangsan.git' 11 | llvm_svn_commit = '251286' 12 | binutils_tarball_format = 'binutils-VERSION.tar.bz2' 13 | binutils_url_format = 'http://ftp.gnu.org/gnu/binutils/TARBALL' 14 | binutils_version = '2.26.1' 15 | gperftools_repo = 'https://github.com/gperftools/gperftools.git' 16 | gperftools_commit = 'c46eb1f3d2f7a2bdc54a52ff7cf5e7392f5aa668' 17 | 18 | 19 | def test(config): 20 | cwd = os.getcwd() 21 | 22 | os.chdir('test') 23 | 24 | if not os.path.exists('shrc'): 25 | raise Exception('no shrc found in directory %s' % testdir) 26 | 27 | try: 28 | f = open('shrc', 'r') 29 | lines = f.readlines() 30 | for line in lines: 31 | (key, _, value) = line.partition('=') 32 | os.environ[key.split()[1]] = value.rstrip().replace('"', '') 33 | finally: 34 | f.close() 35 | 36 | util.make() 37 | 38 | os.environ['LD_LIBRARY_PATH'] = os.path.join(cwd, 'lib') 39 | util.make('test') 40 | 41 | os.chdir(cwd) 42 | 43 | 44 | def prepare_gold(version): 45 | curdir = os.getcwd() 46 | binutils_tarball = binutils_tarball_format.replace('VERSION', version) 47 | binutils_url = binutils_url_format.replace('TARBALL', binutils_tarball) 48 | util.download(binutils_url) 49 | util.untar(binutils_tarball) 50 | os.chdir('binutils-VERSION'.replace('VERSION', version)) 51 | util.configure('--prefix=%s --enable-gold --enable-plugins --disable-werror' % curdir) 52 | util.make('-j4') 53 | util.make('-j4 all-gold') 54 | util.make('install') 55 | os.chdir(curdir) 56 | 57 | 58 | def setup(config): 59 | workdir = os.path.abspath(os.getcwd()) 60 | 61 | if not os.path.exists('dangsan'): 62 | util.git.clone(dangsan_repo) 63 | 64 | if not os.path.exists('llvm-svn'): 65 | util.llvm.checkout_svn(llvm_svn_commit) 66 | os.chdir('llvm-svn') 67 | util.patch(os.path.join(workdir, 'dangsan', 'patches', 'LLVM-gold-plugins-3.8.diff'), '-p0') 68 | util.patch(os.path.join(workdir, 'dangsan', 'patches', 'LLVM-safestack-3.8.diff'), '-p0') 69 | os.chdir('projects/compiler-rt') 70 | util.patch(os.path.join(workdir, 'dangsan', 'patches', 'COMPILERRT-safestack-3.8.diff'), '-p0') 71 | os.chdir(workdir) 72 | 73 | if not os.path.exists('bin/ld'): 74 | prepare_gold(binutils_version) 75 | os.remove('bin/ld') 76 | shutil.copy('bin/ld.gold', 'bin/ld') 77 | 78 | if not os.path.exists('llvm-build'): 79 | os.mkdir('llvm-build') 80 | util.llvm.compile(src_dir=os.path.abspath('llvm-svn'), 81 | build_dir=os.path.abspath('llvm-build'), 82 | install_dir=os.getcwd(), 83 | options=['-DLLVM_BINUTILS_INCDIR=%s/include' % workdir]) 84 | util.llvm.install(os.path.abspath('llvm-build')) 85 | 86 | if not glob.glob('gperftools*'): 87 | util.git.clone(gperftools_repo) 88 | os.chdir('gperftools') 89 | util.git.checkout(gperftools_commit) 90 | 91 | # gperftools patch for both baseline and DangSan 92 | util.git.patch(os.path.join(workdir, 'dangsan', 'patches', 'GPERFTOOLS_SPEEDUP.patch')) 93 | 94 | if config == configs[1] or config == configs[2]: 95 | os.chdir(workdir) 96 | 97 | # Build metapagetable 98 | if not os.path.exists('gperftools-metalloc'): 99 | shutil.move('gperftools', 'gperftools-metalloc') 100 | 101 | if not os.path.exists('metapagetable'): 102 | config_fixedcompression = 'false' 103 | config_metadatabytes = 8 104 | config_deepmetadata = 'false' 105 | config_alloc_size_hook = 'dang_alloc_size_hook' 106 | metalloc_options = [] 107 | metalloc_options.append('-DFIXEDCOMPRESSION=%s' % config_fixedcompression) 108 | metalloc_options.append('-DMETADATABYTES=%d' % config_metadatabytes) 109 | metalloc_options.append('-DDEEPMETADATA=%s' % config_deepmetadata) 110 | metalloc_options.append('-DALLOC_SIZE_HOOK=%s' % config_alloc_size_hook) 111 | os.environ['METALLOC_OPTIONS'] = ' '.join(metalloc_options) 112 | 113 | shutil.copytree(os.path.join('dangsan', 'metapagetable'), 'metapagetable') 114 | os.chdir('metapagetable') 115 | util.make('config') 116 | util.make() 117 | os.chdir(workdir) 118 | 119 | # Apply DanSan patches for gperftool 120 | os.chdir('gperftools-metalloc') 121 | util.git.patch(os.path.join(os.path.dirname(__file__), 'GPERFTOOLS_DANGSAN.patch')) 122 | 123 | util.run('autoreconf -fi') 124 | util.configure('--prefix=%s' % workdir) 125 | util.make('-j4') 126 | util.make('install') 127 | os.chdir(workdir) 128 | 129 | # build llvm-plugins 130 | llvmplugins_dir = os.path.join(workdir, 'llvm-plugins') 131 | libplugins_so = os.path.join(llvmplugins_dir, 'libplugins.so') 132 | if config == configs[1] or config == configs[2]: 133 | if not os.path.exists('staticlib'): 134 | os.environ['PATH'] = ':'.join([os.path.join(workdir, 'bin'), os.environ['PATH']]) 135 | shutil.copytree('dangsan/staticlib', 'staticlib') 136 | os.chdir('staticlib') 137 | util.make('METAPAGETABLEDIR=%s' % os.path.join(workdir, 'metapagetable', 'obj')) 138 | os.chdir(workdir) 139 | 140 | if not os.path.exists(libplugins_so): 141 | os.environ['PATH'] = ':'.join([os.path.join(workdir, 'bin'), os.environ['PATH']]) 142 | os.chdir('dangsan/llvm-plugins') 143 | util.make('-j4 GOLDINSTDIR=%s TARGETDIR=%s' % (workdir, llvmplugins_dir)) 144 | os.chdir(workdir) 145 | 146 | # Create spec config file 147 | print 'creating spec config file...' 148 | 149 | spec_cfg = '-'.join([command, config]) + '.cfg' 150 | 151 | if os.path.exists(spec_cfg): 152 | os.remove(spec_cfg) 153 | 154 | cflags = ['-flto'] 155 | cxxflags = ['-flto'] 156 | ldflags = [] 157 | if config == configs[1] or config == configs[2]: 158 | cflags.append('-fsanitize=safe-stack') 159 | cxxflags.append('-fsanitize=safe-stack') 160 | cxxflags.append('-DSOPLEX_DANGSAN_MASK') 161 | ldflags.append('-Wl,-plugin-opt=-load=%s' % libplugins_so) 162 | ldflags.append('-Wl,-plugin-opt=%s' % '-largestack=false') 163 | # ldflags.append('-Wl,-plugin-opt=%s' % '-stats') # option not found 164 | ldflags.append('-Wl,-plugin-opt=%s' % '-mergedstack=false') 165 | ldflags.append('-Wl,-plugin-opt=%s' % '-stacktracker') 166 | ldflags.append('-Wl,-plugin-opt=%s' % '-globaltracker') 167 | ldflags.append('-Wl,-plugin-opt=%s' % '-pointertracker') 168 | ldflags.append('-Wl,-plugin-opt=%s' % '-FreeSentryLoop') 169 | ldflags.append('-Wl,-plugin-opt=%s' % '-custominline') 170 | ldflags.append('-Wl,-whole-archive,-l:libmetadata.a,-no-whole-archive') # staticlib 171 | ldflags.append('@%s' % os.path.join(workdir, 'metapagetable', 'obj', 'linker-options')) 172 | 173 | extra_libs = ['-ltcmalloc', '-lpthread', '-lunwind'] 174 | extra_libs.append('-L%s' % os.path.join(workdir, 'lib')) 175 | if config == configs[1] or config == configs[2]: 176 | extra_libs.append('-ldl') 177 | extra_libs.append('-L%s' % os.path.join(workdir, 'staticlib', 'obj')) 178 | 179 | if config == configs[2]: 180 | cflags.append('-g') 181 | cxxflags.append('-g') 182 | 183 | cc = [os.path.abspath(os.path.join(workdir, 'bin', 'clang'))] 184 | cc.extend(cflags) 185 | cxx = [os.path.abspath(os.path.join(workdir, 'bin', 'clang++'))] 186 | cxx.extend(cxxflags) 187 | cld = list(cc) 188 | cld.extend(ldflags) 189 | cxxld = list(cxx) 190 | cxxld.extend(ldflags) 191 | 192 | util.spec.create_config(dir=os.getcwd(), file=spec_cfg, 193 | name='-'.join([command, config]), 194 | cc=' '.join(cc), cxx=' '.join(cxx), 195 | cld=' '.join(cld), cxxld=' '.join(cxxld), 196 | extra_libs=' '.join(extra_libs)) 197 | 198 | # create shrc for testing 199 | print('creating test directory...') 200 | 201 | if not os.path.exists('test'): 202 | testdir = os.path.join(os.path.dirname(__file__), 'test') 203 | shutil.copytree(testdir, os.path.join(workdir, 'test')) 204 | 205 | if os.path.exists('test/shrc'): 206 | os.remove('test/shrc') 207 | 208 | util.test.create_shrc( 209 | dir=os.path.abspath('test'), 210 | cc=' '.join(cc), cxx=' '.join(cxx), ld=' '.join(cld), 211 | ldflags=' '.join(extra_libs) 212 | ) 213 | 214 | 215 | def clean(config): 216 | workdir = '-'.join(['dangsan', config]) 217 | if not os.path.exists(workdir): 218 | print 'nothing to clean' 219 | return 220 | 221 | shutil.rmtree(workdir) 222 | 223 | 224 | def run(config): 225 | if config.find('spec') > -1: 226 | print 'running ' + config + '...' 227 | spec_cfg = '-'.join([command, config]) + '.cfg' 228 | benchmarks = util.spec.all_benchmarks 229 | 230 | if config == configs[1] or config == configs[2]: 231 | os.environ['SAFESTACK_OPTIONS'] = '"largestack=true"' 232 | 233 | print 'running spec2006 cpu benchmark %s using %s...' % (', '.join(benchmarks), spec_cfg) 234 | 235 | os.environ['LD_LIBRARY_PATH'] = os.path.join(os.getcwd(), 'lib') 236 | util.spec.runspec(config=os.path.abspath(spec_cfg), 237 | benchmarks=benchmarks) 238 | -------------------------------------------------------------------------------- /lowfat/config/lowfat.errs: -------------------------------------------------------------------------------- 1 | 0x400000000 17179869184 16 0 2 | 0x800000000 17179869184 32 0 3 | 0xc00000000 17179869184 48 0 4 | 0x1000000000 17179869184 64 0 5 | 0x1400000000 17179869184 80 0 6 | 0x1800000000 17179869184 96 0 7 | 0x1c00000000 17179869184 112 0 8 | 0x2000000000 17179869184 128 0 9 | 0x2400000000 17179869184 144 0 10 | 0x2800000000 17179869184 160 0 11 | 0x2c00000000 17179869184 192 0 12 | 0x3000000000 17179869184 224 0 13 | 0x3400000000 17179869184 256 0 14 | 0x3800000000 17179869184 272 0 15 | 0x3c00000000 17179869184 320 0 16 | 0x4000000000 17179869184 384 0 17 | 0x4400000000 17179869184 448 0 18 | 0x4800000000 17179869184 512 0 19 | 0x4c00000000 17179869184 528 0 20 | 0x5000000000 17179869184 640 0 21 | 0x5400000000 17179869184 768 0 22 | 0x5800000000 17179869184 896 0 23 | 0x5c00000000 17179869184 1024 0 24 | 0x6000000000 17179869184 1040 0 25 | 0x6400000000 17179869184 1280 0 26 | 0x6800000000 17179869184 1536 0 27 | 0x6c00000000 17179869184 1792 0 28 | 0x7000000000 17179869184 2048 0 29 | 0x7400000000 17179869184 2064 0 30 | 0x7800000000 17179869184 2560 0 31 | 0x7c00000000 17179869184 3072 0 32 | 0x8000000000 17179869184 3584 0 33 | 0x8400000000 17179869184 4096 0 34 | 0x8800000000 17179869184 4112 0 35 | 0x8c00000000 17179869184 5120 0 36 | 0x9000000000 17179869184 6144 0 37 | 0x9400000000 17179869184 7168 0 38 | 0x9800000000 17179869184 8192 0 39 | 0x9c00000000 17179869184 8208 0 40 | 0xa000000000 17179869184 10240 0 41 | 0xa400000000 17179869184 12288 0 42 | 0xa800000000 17179869184 16384 0 43 | 0xac00000000 17179869184 32768 0 44 | 0xb000000000 17179869184 65536 0 45 | 0xb400000000 17179869184 131072 0 46 | 0xb800000000 17179869184 262144 0 47 | 0xbc00000000 17179869184 524288 0 48 | 0xc000000000 17179869184 1048576 0 49 | 0xc400000000 17179869184 2097152 0 50 | 0xc800000000 17179869184 4194304 0 51 | 0xcc00000000 17179869184 8388608 0 52 | 0xd000000000 17179869184 16777216 0 53 | 0xd400000000 17179869184 33554432 1 54 | 0xd800000000 17179869184 67108864 3 55 | 0xdc00000000 17179869184 134217728 7 56 | 0xe000000000 17179869184 268435456 14 57 | 0xe400000000 17179869184 536870912 29 58 | 0xe800000000 17179869184 1073741824 59 59 | 0xec00000000 17179869184 2147483648 120 60 | 0xf000000000 17179869184 4294967296 244 61 | 0x800000000 34359738368 16 0 62 | 0x1000000000 34359738368 32 0 63 | 0x1800000000 34359738368 48 0 64 | 0x2000000000 34359738368 64 0 65 | 0x2800000000 34359738368 80 0 66 | 0x3000000000 34359738368 96 0 67 | 0x3800000000 34359738368 112 0 68 | 0x4000000000 34359738368 128 0 69 | 0x4800000000 34359738368 144 0 70 | 0x5000000000 34359738368 160 0 71 | 0x5800000000 34359738368 192 0 72 | 0x6000000000 34359738368 224 0 73 | 0x6800000000 34359738368 256 0 74 | 0x7000000000 34359738368 272 0 75 | 0x7800000000 34359738368 320 0 76 | 0x8000000000 34359738368 384 0 77 | 0x8800000000 34359738368 448 0 78 | 0x9000000000 34359738368 512 0 79 | 0x9800000000 34359738368 528 0 80 | 0xa000000000 34359738368 640 0 81 | 0xa800000000 34359738368 768 0 82 | 0xb000000000 34359738368 896 0 83 | 0xb800000000 34359738368 1024 0 84 | 0xc000000000 34359738368 1040 0 85 | 0xc800000000 34359738368 1280 0 86 | 0xd000000000 34359738368 1536 0 87 | 0xd800000000 34359738368 1792 0 88 | 0xe000000000 34359738368 2048 0 89 | 0xe800000000 34359738368 2064 0 90 | 0xf000000000 34359738368 2560 0 91 | 0xf800000000 34359738368 3072 0 92 | 0x10000000000 34359738368 3584 0 93 | 0x10800000000 34359738368 4096 0 94 | 0x11000000000 34359738368 4112 0 95 | 0x11800000000 34359738368 5120 0 96 | 0x12000000000 34359738368 6144 0 97 | 0x12800000000 34359738368 7168 0 98 | 0x13000000000 34359738368 8192 0 99 | 0x13800000000 34359738368 8208 0 100 | 0x14000000000 34359738368 10240 0 101 | 0x14800000000 34359738368 12288 0 102 | 0x15000000000 34359738368 16384 0 103 | 0x15800000000 34359738368 32768 0 104 | 0x16000000000 34359738368 65536 0 105 | 0x16800000000 34359738368 131072 0 106 | 0x17000000000 34359738368 262144 0 107 | 0x17800000000 34359738368 524288 0 108 | 0x18000000000 34359738368 1048576 0 109 | 0x18800000000 34359738368 2097152 0 110 | 0x19000000000 34359738368 4194304 0 111 | 0x19800000000 34359738368 8388608 0 112 | 0x1a000000000 34359738368 16777216 1 113 | 0x1a800000000 34359738368 33554432 3 114 | 0x1b000000000 34359738368 67108864 6 115 | 0x1b800000000 34359738368 134217728 14 116 | 0x1c000000000 34359738368 268435456 28 117 | 0x1c800000000 34359738368 536870912 58 118 | 0x1d000000000 34359738368 1073741824 118 119 | 0x1d800000000 34359738368 2147483648 240 120 | 0x1e000000000 34359738368 4294967296 488 121 | 0x1e800000000 34359738368 8589934592 995 122 | 0x1000000000 68719476736 16 0 123 | 0x2000000000 68719476736 32 0 124 | 0x3000000000 68719476736 48 0 125 | 0x4000000000 68719476736 64 0 126 | 0x5000000000 68719476736 80 0 127 | 0x6000000000 68719476736 96 0 128 | 0x7000000000 68719476736 112 0 129 | 0x8000000000 68719476736 128 0 130 | 0x9000000000 68719476736 144 0 131 | 0xa000000000 68719476736 160 0 132 | 0xb000000000 68719476736 192 0 133 | 0xc000000000 68719476736 224 0 134 | 0xd000000000 68719476736 256 0 135 | 0xe000000000 68719476736 272 0 136 | 0xf000000000 68719476736 320 0 137 | 0x10000000000 68719476736 384 0 138 | 0x11000000000 68719476736 448 0 139 | 0x12000000000 68719476736 512 0 140 | 0x13000000000 68719476736 528 0 141 | 0x14000000000 68719476736 640 0 142 | 0x15000000000 68719476736 768 0 143 | 0x16000000000 68719476736 896 0 144 | 0x17000000000 68719476736 1024 0 145 | 0x18000000000 68719476736 1040 0 146 | 0x19000000000 68719476736 1280 0 147 | 0x1a000000000 68719476736 1536 0 148 | 0x1b000000000 68719476736 1792 0 149 | 0x1c000000000 68719476736 2048 0 150 | 0x1d000000000 68719476736 2064 0 151 | 0x1e000000000 68719476736 2560 0 152 | 0x1f000000000 68719476736 3072 0 153 | 0x20000000000 68719476736 3584 0 154 | 0x21000000000 68719476736 4096 0 155 | 0x22000000000 68719476736 4112 0 156 | 0x23000000000 68719476736 5120 0 157 | 0x24000000000 68719476736 6144 0 158 | 0x25000000000 68719476736 7168 0 159 | 0x26000000000 68719476736 8192 0 160 | 0x27000000000 68719476736 8208 0 161 | 0x28000000000 68719476736 10240 0 162 | 0x29000000000 68719476736 12288 0 163 | 0x2a000000000 68719476736 16384 0 164 | 0x2b000000000 68719476736 32768 0 165 | 0x2c000000000 68719476736 65536 0 166 | 0x2d000000000 68719476736 131072 0 167 | 0x2e000000000 68719476736 262144 0 168 | 0x2f000000000 68719476736 524288 0 169 | 0x30000000000 68719476736 1048576 0 170 | 0x31000000000 68719476736 2097152 0 171 | 0x32000000000 68719476736 4194304 0 172 | 0x33000000000 68719476736 8388608 1 173 | 0x34000000000 68719476736 16777216 3 174 | 0x35000000000 68719476736 33554432 6 175 | 0x36000000000 68719476736 67108864 13 176 | 0x37000000000 68719476736 134217728 28 177 | 0x38000000000 68719476736 268435456 57 178 | 0x39000000000 68719476736 536870912 116 179 | 0x3a000000000 68719476736 1073741824 236 180 | 0x3b000000000 68719476736 2147483648 480 181 | 0x3c000000000 68719476736 4294967296 976 182 | 0x3d000000000 68719476736 8589934592 1987 183 | 0x3e000000000 68719476736 17179869184 4047 184 | 0x2000000000 137438953472 16 0 185 | 0x4000000000 137438953472 32 0 186 | 0x6000000000 137438953472 48 0 187 | 0x8000000000 137438953472 64 0 188 | 0xa000000000 137438953472 80 0 189 | 0xc000000000 137438953472 96 0 190 | 0xe000000000 137438953472 112 0 191 | 0x10000000000 137438953472 128 0 192 | 0x12000000000 137438953472 144 0 193 | 0x14000000000 137438953472 160 0 194 | 0x16000000000 137438953472 192 0 195 | 0x18000000000 137438953472 224 0 196 | 0x1a000000000 137438953472 256 0 197 | 0x1c000000000 137438953472 272 0 198 | 0x1e000000000 137438953472 320 0 199 | 0x20000000000 137438953472 384 0 200 | 0x22000000000 137438953472 448 0 201 | 0x24000000000 137438953472 512 0 202 | 0x26000000000 137438953472 528 0 203 | 0x28000000000 137438953472 640 0 204 | 0x2a000000000 137438953472 768 0 205 | 0x2c000000000 137438953472 896 0 206 | 0x2e000000000 137438953472 1024 0 207 | 0x30000000000 137438953472 1040 0 208 | 0x32000000000 137438953472 1280 0 209 | 0x34000000000 137438953472 1536 0 210 | 0x36000000000 137438953472 1792 0 211 | 0x38000000000 137438953472 2048 0 212 | 0x3a000000000 137438953472 2064 0 213 | 0x3c000000000 137438953472 2560 0 214 | 0x3e000000000 137438953472 3072 0 215 | 0x40000000000 137438953472 3584 0 216 | 0x42000000000 137438953472 4096 0 217 | 0x44000000000 137438953472 4112 0 218 | 0x46000000000 137438953472 5120 0 219 | 0x48000000000 137438953472 6144 0 220 | 0x4a000000000 137438953472 7168 0 221 | 0x4c000000000 137438953472 8192 0 222 | 0x4e000000000 137438953472 8208 0 223 | 0x50000000000 137438953472 10240 0 224 | 0x52000000000 137438953472 12288 0 225 | 0x54000000000 137438953472 16384 0 226 | 0x56000000000 137438953472 32768 0 227 | 0x58000000000 137438953472 65536 0 228 | 0x5a000000000 137438953472 131072 0 229 | 0x5c000000000 137438953472 262144 0 230 | 0x5e000000000 137438953472 524288 0 231 | 0x60000000000 137438953472 1048576 0 232 | 0x62000000000 137438953472 2097152 0 233 | 0x64000000000 137438953472 4194304 1 234 | 0x66000000000 137438953472 8388608 3 235 | 0x68000000000 137438953472 16777216 6 236 | 0x6a000000000 137438953472 33554432 13 237 | 0x6c000000000 137438953472 67108864 27 238 | 0x6e000000000 137438953472 134217728 56 239 | 0x70000000000 137438953472 268435456 114 240 | 0x72000000000 137438953472 536870912 232 241 | 0x74000000000 137438953472 1073741824 472 242 | 0x76000000000 137438953472 2147483648 960 243 | 0x78000000000 137438953472 4294967296 1952 244 | 0x7a000000000 137438953472 8589934592 3971 245 | 0x7c000000000 137438953472 17179869184 8079 246 | 0x7e000000000 137438953472 34359738368 16447 247 | 0x4000000000 274877906944 16 0 248 | 0x8000000000 274877906944 32 0 249 | 0xc000000000 274877906944 48 0 250 | 0x10000000000 274877906944 64 0 251 | 0x14000000000 274877906944 80 0 252 | 0x18000000000 274877906944 96 0 253 | 0x1c000000000 274877906944 112 0 254 | 0x20000000000 274877906944 128 0 255 | 0x24000000000 274877906944 144 0 256 | 0x28000000000 274877906944 160 0 257 | 0x2c000000000 274877906944 192 0 258 | 0x30000000000 274877906944 224 0 259 | 0x34000000000 274877906944 256 0 260 | 0x38000000000 274877906944 272 0 261 | 0x3c000000000 274877906944 320 0 262 | 0x40000000000 274877906944 384 0 263 | 0x44000000000 274877906944 448 0 264 | 0x48000000000 274877906944 512 0 265 | 0x4c000000000 274877906944 528 0 266 | 0x50000000000 274877906944 640 0 267 | 0x54000000000 274877906944 768 0 268 | 0x58000000000 274877906944 896 0 269 | 0x5c000000000 274877906944 1024 0 270 | 0x60000000000 274877906944 1040 0 271 | 0x64000000000 274877906944 1280 0 272 | 0x68000000000 274877906944 1536 0 273 | 0x6c000000000 274877906944 1792 0 274 | 0x70000000000 274877906944 2048 0 275 | 0x74000000000 274877906944 2064 0 276 | 0x78000000000 274877906944 2560 0 277 | 0x7c000000000 274877906944 3072 0 278 | 0x80000000000 274877906944 3584 0 279 | 0x84000000000 274877906944 4096 0 280 | 0x88000000000 274877906944 4112 0 281 | 0x8c000000000 274877906944 5120 0 282 | 0x90000000000 274877906944 6144 0 283 | 0x94000000000 274877906944 7168 0 284 | 0x98000000000 274877906944 8192 0 285 | 0x9c000000000 274877906944 8208 0 286 | 0xa0000000000 274877906944 10240 0 287 | 0xa4000000000 274877906944 12288 0 288 | 0xa8000000000 274877906944 16384 0 289 | 0xac000000000 274877906944 32768 0 290 | 0xb0000000000 274877906944 65536 0 291 | 0xb4000000000 274877906944 131072 0 292 | 0xb8000000000 274877906944 262144 0 293 | 0xbc000000000 274877906944 524288 0 294 | 0xc0000000000 274877906944 1048576 0 295 | 0xc4000000000 274877906944 2097152 1 296 | 0xc8000000000 274877906944 4194304 3 297 | 0xcc000000000 274877906944 8388608 6 298 | 0xd0000000000 274877906944 16777216 13 299 | 0xd4000000000 274877906944 33554432 27 300 | 0xd8000000000 274877906944 67108864 55 301 | 0xdc000000000 274877906944 134217728 112 302 | 0xe0000000000 274877906944 268435456 228 303 | 0xe4000000000 274877906944 536870912 464 304 | 0xe8000000000 274877906944 1073741824 944 305 | 0xec000000000 274877906944 2147483648 1920 306 | 0xf0000000000 274877906944 4294967296 3904 307 | 0xf4000000000 274877906944 8589934592 7939 308 | 0xf8000000000 274877906944 17179869184 16143 309 | 0xfc000000000 274877906944 34359738368 32831 310 | 0x100000000000 274877906944 68719476736 66815 311 | 0x8000000000 549755813888 16 0 312 | 0x10000000000 549755813888 32 0 313 | 0x18000000000 549755813888 48 0 314 | 0x20000000000 549755813888 64 0 315 | 0x28000000000 549755813888 80 0 316 | 0x30000000000 549755813888 96 0 317 | 0x38000000000 549755813888 112 0 318 | 0x40000000000 549755813888 128 0 319 | 0x48000000000 549755813888 144 0 320 | 0x50000000000 549755813888 160 0 321 | 0x58000000000 549755813888 192 0 322 | 0x60000000000 549755813888 224 0 323 | 0x68000000000 549755813888 256 0 324 | 0x70000000000 549755813888 272 0 325 | 0x78000000000 549755813888 320 0 326 | 0x80000000000 549755813888 384 0 327 | 0x88000000000 549755813888 448 0 328 | 0x90000000000 549755813888 512 0 329 | 0x98000000000 549755813888 528 0 330 | 0xa0000000000 549755813888 640 0 331 | 0xa8000000000 549755813888 768 0 332 | 0xb0000000000 549755813888 896 0 333 | 0xb8000000000 549755813888 1024 0 334 | 0xc0000000000 549755813888 1040 0 335 | 0xc8000000000 549755813888 1280 0 336 | 0xd0000000000 549755813888 1536 0 337 | 0xd8000000000 549755813888 1792 0 338 | 0xe0000000000 549755813888 2048 0 339 | 0xe8000000000 549755813888 2064 0 340 | 0xf0000000000 549755813888 2560 0 341 | 0xf8000000000 549755813888 3072 0 342 | 0x100000000000 549755813888 3584 0 343 | 0x108000000000 549755813888 4096 0 344 | 0x110000000000 549755813888 4112 0 345 | 0x118000000000 549755813888 5120 0 346 | 0x120000000000 549755813888 6144 0 347 | 0x128000000000 549755813888 7168 0 348 | 0x130000000000 549755813888 8192 0 349 | 0x138000000000 549755813888 8208 0 350 | 0x140000000000 549755813888 10240 0 351 | 0x148000000000 549755813888 12288 0 352 | 0x150000000000 549755813888 16384 0 353 | 0x158000000000 549755813888 32768 0 354 | 0x160000000000 549755813888 65536 0 355 | 0x168000000000 549755813888 131072 0 356 | 0x170000000000 549755813888 262144 0 357 | 0x178000000000 549755813888 524288 0 358 | 0x180000000000 549755813888 1048576 1 359 | 0x188000000000 549755813888 2097152 3 360 | 0x190000000000 549755813888 4194304 6 361 | 0x198000000000 549755813888 8388608 13 362 | 0x1a0000000000 549755813888 16777216 26 363 | 0x1a8000000000 549755813888 33554432 54 364 | 0x1b0000000000 549755813888 67108864 110 365 | 0x1b8000000000 549755813888 134217728 224 366 | 0x1c0000000000 549755813888 268435456 456 367 | 0x1c8000000000 549755813888 536870912 928 368 | 0x1d0000000000 549755813888 1073741824 1888 369 | 0x1d8000000000 549755813888 2147483648 3840 370 | 0x1e0000000000 549755813888 4294967296 7808 371 | 0x1e8000000000 549755813888 8589934592 15875 372 | 0x1f0000000000 549755813888 17179869184 32271 373 | 0x1f8000000000 549755813888 34359738368 65599 374 | 0x200000000000 549755813888 68719476736 133375 375 | 0x10000000000 1099511627776 16 0 376 | 0x20000000000 1099511627776 32 0 377 | 0x30000000000 1099511627776 48 0 378 | 0x40000000000 1099511627776 64 0 379 | 0x50000000000 1099511627776 80 0 380 | 0x60000000000 1099511627776 96 0 381 | 0x70000000000 1099511627776 112 0 382 | 0x80000000000 1099511627776 128 0 383 | 0x90000000000 1099511627776 144 0 384 | 0xa0000000000 1099511627776 160 0 385 | 0xb0000000000 1099511627776 192 0 386 | 0xc0000000000 1099511627776 224 0 387 | 0xd0000000000 1099511627776 256 0 388 | 0xe0000000000 1099511627776 272 0 389 | 0xf0000000000 1099511627776 320 0 390 | 0x100000000000 1099511627776 384 0 391 | 0x110000000000 1099511627776 448 0 392 | 0x120000000000 1099511627776 512 0 393 | 0x130000000000 1099511627776 528 0 394 | 0x140000000000 1099511627776 640 0 395 | 0x150000000000 1099511627776 768 0 396 | 0x160000000000 1099511627776 896 0 397 | 0x170000000000 1099511627776 1024 0 398 | 0x180000000000 1099511627776 1040 0 399 | 0x190000000000 1099511627776 1280 0 400 | 0x1a0000000000 1099511627776 1536 0 401 | 0x1b0000000000 1099511627776 1792 0 402 | 0x1c0000000000 1099511627776 2048 0 403 | 0x1d0000000000 1099511627776 2064 0 404 | 0x1e0000000000 1099511627776 2560 0 405 | 0x1f0000000000 1099511627776 3072 0 406 | 0x200000000000 1099511627776 3584 0 407 | 0x210000000000 1099511627776 4096 0 408 | 0x220000000000 1099511627776 4112 0 409 | 0x230000000000 1099511627776 5120 0 410 | 0x240000000000 1099511627776 6144 0 411 | 0x250000000000 1099511627776 7168 0 412 | 0x260000000000 1099511627776 8192 0 413 | 0x270000000000 1099511627776 8208 0 414 | 0x280000000000 1099511627776 10240 0 415 | 0x290000000000 1099511627776 12288 0 416 | 0x2a0000000000 1099511627776 16384 0 417 | 0x2b0000000000 1099511627776 32768 0 418 | 0x2c0000000000 1099511627776 65536 0 419 | 0x2d0000000000 1099511627776 131072 0 420 | 0x2e0000000000 1099511627776 262144 0 421 | 0x2f0000000000 1099511627776 524288 1 422 | 0x300000000000 1099511627776 1048576 3 423 | 0x310000000000 1099511627776 2097152 6 424 | 0x320000000000 1099511627776 4194304 12 425 | 0x330000000000 1099511627776 8388608 26 426 | 0x340000000000 1099511627776 16777216 53 427 | 0x350000000000 1099511627776 33554432 108 428 | 0x360000000000 1099511627776 67108864 220 429 | 0x370000000000 1099511627776 134217728 448 430 | 0x380000000000 1099511627776 268435456 912 431 | 0x390000000000 1099511627776 536870912 1856 432 | 0x3a0000000000 1099511627776 1073741824 3776 433 | 0x3b0000000000 1099511627776 2147483648 7680 434 | 0x3c0000000000 1099511627776 4294967296 15616 435 | 0x3d0000000000 1099511627776 8589934592 31747 436 | 0x3e0000000000 1099511627776 17179869184 64527 437 | 0x3f0000000000 1099511627776 34359738368 131135 438 | 0x400000000000 1099511627776 68719476736 266495 439 | -------------------------------------------------------------------------------- /typesan/clang.patch: -------------------------------------------------------------------------------- 1 | diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def 2 | index 4b68593..49cd4d1 100644 3 | --- a/include/clang/Basic/Sanitizers.def 4 | +++ b/include/clang/Basic/Sanitizers.def 5 | @@ -50,6 +50,9 @@ SANITIZER("memory", Memory) 6 | // ThreadSanitizer 7 | SANITIZER("thread", Thread) 8 | 9 | +// TypeSan 10 | +SANITIZER("typesan", TypeSan) 11 | + 12 | // LeakSanitizer 13 | SANITIZER("leak", Leak) 14 | 15 | diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h 16 | index 072ddee..9bf6435 100644 17 | --- a/include/clang/Driver/SanitizerArgs.h 18 | +++ b/include/clang/Driver/SanitizerArgs.h 19 | @@ -46,6 +46,8 @@ class SanitizerArgs { 20 | bool needsSharedAsanRt() const { return AsanSharedRuntime; } 21 | bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); } 22 | bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); } 23 | + bool needsTypeSanRt() const { return Sanitizers.has(SanitizerKind::TypeSan); } 24 | + bool needsMetallocRt() const { return Sanitizers.has(SanitizerKind::TypeSan); } 25 | bool needsLsanRt() const { 26 | return Sanitizers.has(SanitizerKind::Leak) && 27 | !Sanitizers.has(SanitizerKind::Address); 28 | diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp 29 | index 9727fc9..4d2bcaf 100644 30 | --- a/lib/CodeGen/BackendUtil.cpp 31 | +++ b/lib/CodeGen/BackendUtil.cpp 32 | @@ -178,6 +178,15 @@ static void addBoundsCheckingPass(const PassManagerBuilder &Builder, 33 | PM.add(createBoundsCheckingPass()); 34 | } 35 | 36 | +static void addTypeSanPass(const PassManagerBuilder &Builder, 37 | + PassManagerBase &PM) { 38 | + PM.add(createTypeSanPass()); 39 | +} 40 | + 41 | +static void addTypeSanTreePass(const PassManagerBuilder &Builder, 42 | + PassManagerBase &PM) { 43 | + PM.add(createTypeSanTreePass()); 44 | +} 45 | static void addSanitizerCoveragePass(const PassManagerBuilder &Builder, 46 | legacy::PassManagerBase &PM) { 47 | const PassManagerBuilderWrapper &BuilderWrapper = 48 | @@ -404,6 +413,18 @@ void EmitAssemblyHelper::CreatePasses(FunctionInfoIndex *FunctionIndex) { 49 | addDataFlowSanitizerPass); 50 | } 51 | 52 | + 53 | + if (LangOpts.Sanitize.has(SanitizerKind::TypeSan)) { 54 | + PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, 55 | + addTypeSanTreePass); 56 | + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, 57 | + addTypeSanTreePass); 58 | + PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, 59 | + addTypeSanPass); 60 | + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, 61 | + addTypeSanPass); 62 | + } 63 | + 64 | // Set up the per-function pass manager. 65 | legacy::FunctionPassManager *FPM = getPerFunctionPasses(); 66 | if (CodeGenOpts.VerifyModule) 67 | @@ -616,6 +637,10 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, 68 | if (CodeGenOpts.OptimizationLevel > 0) 69 | PM->add(createObjCARCContractPass()); 70 | 71 | + // Add passes to reorganize memory layout for metadata tracking 72 | + if (LangOpts.Sanitize.has(SanitizerKind::TypeSan)) 73 | + PM->add(createMetaStackPass()); 74 | + 75 | if (TM->addPassesToEmitFile(*PM, OS, CGFT, 76 | /*DisableVerify=*/!CodeGenOpts.VerifyModule)) { 77 | Diags.Report(diag::err_fe_unable_to_interface_with_target); 78 | diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp 79 | index 8a82be9..2217ac3 100644 80 | --- a/lib/CodeGen/CGClass.cpp 81 | +++ b/lib/CodeGen/CGClass.cpp 82 | @@ -2516,6 +2516,152 @@ void CodeGenFunction::EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, 83 | EmitVTablePtrCheck(RD, VTable, TCK, Loc); 84 | } 85 | 86 | +// crc32 bit 87 | +// Reverses (reflects) bits in a 32-bit word. 88 | +unsigned int crc32c(unsigned char *message) { 89 | + int i, j; 90 | + unsigned int byte, crc, mask; 91 | + static unsigned int table[256]; 92 | + 93 | + /* Set up the table, if necessary. */ 94 | + 95 | + if (table[1] == 0) { 96 | + for (byte = 0; byte <= 255; byte++) { 97 | + crc = byte; 98 | + for (j = 7; j >= 0; j--) { // Do eight times. 99 | + mask = -(crc & 1); 100 | + crc = (crc >> 1) ^ (0xEDB88320 & mask); 101 | + } 102 | + table[byte] = crc; 103 | + } 104 | + } 105 | + 106 | + /* Through with table setup, now calculate the CRC. */ 107 | + 108 | + i = 0; 109 | + crc = 0xFFFFFFFF; 110 | + while ((byte = message[i]) != 0) { 111 | + crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]; 112 | + i = i + 1; 113 | + } 114 | + return ~crc; 115 | +} 116 | + 117 | +uint64_t crc64c(unsigned char *message) { 118 | + int i, j; 119 | + unsigned int byte; 120 | + uint64_t crc, mask; 121 | + static uint64_t table[256]; 122 | + 123 | + /* Set up the table, if necessary. */ 124 | + 125 | + if (table[1] == 0) { 126 | + for (byte = 0; byte <= 255; byte++) { 127 | + crc = byte; 128 | + for (j = 7; j >= 0; j--) { // Do eight times. 129 | + mask = -(crc & 1); 130 | + crc = (crc >> 1) ^ (0xC96C5795D7870F42UL & mask); 131 | + } 132 | + table[byte] = crc; 133 | + } 134 | + } 135 | + 136 | + /* Through with table setup, now calculate the CRC. */ 137 | + 138 | + i = 0; 139 | + crc = 0xFFFFFFFFFFFFFFFFUL; 140 | + while ((byte = message[i]) != 0) { 141 | + crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]; 142 | + i = i + 1; 143 | + } 144 | + return ~crc; 145 | +} 146 | + 147 | +uint64_t GetHashValue(std::string str) 148 | +{ 149 | + unsigned char *className = new unsigned char[str.length() + 1]; 150 | + strcpy((char *)className, str.c_str()); 151 | + 152 | + return crc64c(className); 153 | +} 154 | + 155 | +void remove_useless_str(std::string& str) { 156 | + 157 | + std::string::size_type i; 158 | + 159 | + std::string basesuffix = ".base"; 160 | + 161 | + while( (i =str.find("*")) != std::string::npos) { 162 | + str.erase(i, 1); 163 | + } 164 | + 165 | + while( (i =str.find("'")) != std::string::npos) { 166 | + str.erase(i, 1); 167 | + } 168 | + 169 | + i = str.find(basesuffix); 170 | + 171 | + if (i != std::string::npos) 172 | + str.erase(i, basesuffix.length()); 173 | +} 174 | + 175 | +void CodeGenFunction::EmitTypeSanCheckForCast(QualType T, 176 | + llvm::Value *Base, 177 | + bool MayBeNull, 178 | + CFITypeCheckKind TCK, 179 | + SourceLocation Loc) { 180 | + 181 | + auto *ClassTy = T->getAs(); 182 | + if (!ClassTy) 183 | + return; 184 | + 185 | + const CXXRecordDecl *ClassDecl = cast(ClassTy->getDecl()); 186 | + if (ClassDecl->isCompleteDefinition() && ClassDecl && ClassDecl->hasDefinition() && !ClassDecl->isAnonymousStructOrUnion()) { 187 | + llvm::Constant *StaticData[] = { 188 | + EmitCheckSourceLocation(Loc), 189 | + }; 190 | + 191 | + auto &layout = getTypes().getCGRecordLayout(ClassDecl); 192 | + std::string dstStr = layout.getLLVMType()->getName(); 193 | + remove_useless_str(dstStr); 194 | + uint64_t dstValue = GetHashValue(dstStr); 195 | + llvm::Value *cast = llvm::ConstantInt::get(Int64Ty, dstValue); 196 | + llvm::Value *DynamicArgs[] = { Base, cast }; 197 | + 198 | + TypeSanEmitCheck("__type_casting_verification", StaticData, 199 | + DynamicArgs, dstStr, dstValue); 200 | + } 201 | +} 202 | + 203 | +void CodeGenFunction::EmitTypeSanCheckForChangingCast(QualType T, 204 | + llvm::Value *Base, 205 | + llvm::Value *Derived, 206 | + bool MayBeNull, 207 | + CFITypeCheckKind TCK, 208 | + SourceLocation Loc) { 209 | + 210 | + auto *ClassTy = T->getAs(); 211 | + if (!ClassTy) 212 | + return; 213 | + 214 | + const CXXRecordDecl *ClassDecl = cast(ClassTy->getDecl()); 215 | + if (ClassDecl->isCompleteDefinition() && ClassDecl && ClassDecl->hasDefinition() && !ClassDecl->isAnonymousStructOrUnion()) { 216 | + llvm::Constant *StaticData[] = { 217 | + EmitCheckSourceLocation(Loc), 218 | + }; 219 | + 220 | + auto &layout = getTypes().getCGRecordLayout(ClassDecl); 221 | + std::string dstStr = layout.getLLVMType()->getName(); 222 | + remove_useless_str(dstStr); 223 | + uint64_t dstValue = GetHashValue(dstStr); 224 | + llvm::Value *cast = llvm::ConstantInt::get(Int64Ty, dstValue); 225 | + llvm::Value *DynamicArgs[] = { Base, Derived, cast }; 226 | + 227 | + TypeSanEmitCheck("__changing_type_casting_verification", StaticData, 228 | + DynamicArgs, dstStr, dstValue); 229 | + } 230 | +} 231 | + 232 | void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, 233 | llvm::Value *Derived, 234 | bool MayBeNull, 235 | diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp 236 | index 4a0f149..c2e1355 100644 237 | --- a/lib/CodeGen/CGExpr.cpp 238 | +++ b/lib/CodeGen/CGExpr.cpp 239 | @@ -2446,6 +2446,53 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF, 240 | } 241 | } 242 | 243 | +void CodeGenFunction::TypeSanEmitCheck( 244 | +// ArrayRef> Checked, 245 | + StringRef FunctionName, ArrayRef StaticArgs, 246 | + ArrayRef DynamicArgs, 247 | + std::string dstStr, 248 | + uint64_t dstValue) { 249 | + int blacklisted; 250 | + 251 | + blacklisted = CGM.getContext().getSanitizerBlacklist().isBlacklistedFunction(CurFn->getName()) ? 1 : 0; 252 | + if (blacklisted) return; 253 | + 254 | + llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs); 255 | + auto *InfoPtr = 256 | + new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false, 257 | + llvm::GlobalVariable::PrivateLinkage, Info); 258 | + InfoPtr->setUnnamedAddr(true); 259 | + CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr); 260 | + 261 | + SmallVector Args; 262 | + SmallVector ArgTypes; 263 | + Args.reserve(DynamicArgs.size() + 1); 264 | + ArgTypes.reserve(DynamicArgs.size() + 1); 265 | + 266 | + // Handler functions take an i8* pointing to the (handler-specific) static 267 | + // information block, followed by a sequence of intptr_t arguments 268 | + // representing operand values. 269 | + //Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy)); 270 | + //ArgTypes.push_back(Int8PtrTy); 271 | + for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) { 272 | + Args.push_back(EmitCheckValue(DynamicArgs[i])); 273 | + ArgTypes.push_back(IntPtrTy); 274 | + } 275 | + 276 | + llvm::AttrBuilder B; 277 | + B.addAttribute(llvm::Attribute::UWTable); 278 | + 279 | + llvm::FunctionType *FnType = 280 | + llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false); 281 | + 282 | + llvm::Value *Fn = CGM.CreateRuntimeFunction( 283 | + FnType, FunctionName, 284 | + llvm::AttributeSet::get(getLLVMContext(), 285 | + llvm::AttributeSet::FunctionIndex, B)); 286 | + 287 | + EmitNounwindRuntimeCall(Fn, Args); 288 | +} 289 | + 290 | void CodeGenFunction::EmitCheck( 291 | ArrayRef> Checked, 292 | StringRef CheckName, ArrayRef StaticArgs, 293 | @@ -3618,6 +3665,25 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { 294 | EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(), 295 | Derived.getPointer(), E->getType()); 296 | 297 | + // Check bad-casting by TypeSan 298 | + if (SanOpts.has(SanitizerKind::TypeSan)) { 299 | + llvm::Value *NonVirtualOffset = CGM.GetNonVirtualBaseClassOffset(DerivedClassDecl, E->path_begin(), E->path_end()); 300 | + if (!NonVirtualOffset) { 301 | + EmitTypeSanCheckForCast(E->getType(), 302 | + LV.getAddress().getPointer(), 303 | + /*MayBeNull=*/false, 304 | + CFITCK_DerivedCast, 305 | + E->getLocStart()); 306 | + } else { 307 | + EmitTypeSanCheckForChangingCast(E->getType(), 308 | + LV.getAddress().getPointer(), 309 | + Derived.getPointer(), 310 | + /*MayBeNull=*/false, 311 | + CFITCK_DerivedCast, 312 | + E->getLocStart()); 313 | + } 314 | + } 315 | + 316 | if (SanOpts.has(SanitizerKind::CFIDerivedCast)) 317 | EmitVTablePtrCheckForCast(E->getType(), Derived.getPointer(), 318 | /*MayBeNull=*/false, 319 | diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp 320 | index 540e01f..e7c530b 100644 321 | --- a/lib/CodeGen/CGExprScalar.cpp 322 | +++ b/lib/CodeGen/CGExprScalar.cpp 323 | @@ -1442,6 +1442,26 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { 324 | CodeGenFunction::CFITCK_DerivedCast, 325 | CE->getLocStart()); 326 | 327 | + if (CGF.SanOpts.has(SanitizerKind::TypeSan)) 328 | + { 329 | + llvm::Value *NonVirtualOffset = CGF.CGM.GetNonVirtualBaseClassOffset(DerivedClassDecl, CE->path_begin(), CE->path_end()); 330 | + if (!NonVirtualOffset) { 331 | + CGF.EmitTypeSanCheckForCast(DestTy->getPointeeType(), 332 | + Base.getPointer(), 333 | + /*MayBeNull=*/false, 334 | + CodeGenFunction::CFITCK_DerivedCast, 335 | + CE->getLocStart()); 336 | + } else { 337 | + CGF.EmitTypeSanCheckForChangingCast(DestTy->getPointeeType(), 338 | + Base.getPointer(), 339 | + Derived.getPointer(), 340 | + /*MayBeNull=*/false, 341 | + CodeGenFunction::CFITCK_DerivedCast, 342 | + CE->getLocStart()); 343 | + } 344 | + } 345 | + 346 | + 347 | return Derived.getPointer(); 348 | } 349 | case CK_UncheckedDerivedToBase: 350 | diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h 351 | index 85d5f7a..3e6c089 100644 352 | --- a/lib/CodeGen/CodeGenFunction.h 353 | +++ b/lib/CodeGen/CodeGenFunction.h 354 | @@ -3048,6 +3048,23 @@ public: 355 | StringRef CheckName, ArrayRef StaticArgs, 356 | ArrayRef DynamicArgs); 357 | 358 | + 359 | + /// \brief Emit a HexEmitCheck 360 | + void TypeSanEmitCheck(StringRef CheckName, ArrayRef StaticArgs, 361 | + ArrayRef DynamicArgs, 362 | + std::string dstStr, 363 | + uint64_t dstValue); 364 | + 365 | + /// \brief Emit a HexEmitTypeSanCheckerForCast 366 | + void EmitTypeSanCheckForCast(QualType T, llvm::Value *Base, 367 | + bool MayBeNull, CFITypeCheckKind TCK, 368 | + SourceLocation Loc); 369 | + 370 | + /// \brief Emit a HexEmitTypeSanCheckerForChangingCast 371 | + void EmitTypeSanCheckForChangingCast(QualType T, llvm::Value *Base, llvm::Value *Derived, 372 | + bool MayBeNull, CFITypeCheckKind TCK, 373 | + SourceLocation Loc); 374 | + 375 | /// \brief Emit a slow path cross-DSO CFI check which calls __cfi_slowpath 376 | /// if Cond if false. 377 | void EmitCfiSlowPathCheck(SanitizerMask Kind, llvm::Value *Cond, 378 | diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp 379 | index 554f9ff..0b31b14 100644 380 | --- a/lib/CodeGen/CodeGenTypes.cpp 381 | +++ b/lib/CodeGen/CodeGenTypes.cpp 382 | @@ -49,26 +49,47 @@ void CodeGenTypes::addRecordTypeName(const RecordDecl *RD, 383 | StringRef suffix) { 384 | SmallString<256> TypeName; 385 | llvm::raw_svector_ostream OS(TypeName); 386 | - OS << RD->getKindName() << '.'; 387 | + SmallString<256> TypeNameRtti; 388 | + llvm::raw_svector_ostream OSR(TypeNameRtti); 389 | 390 | // Name the codegen type after the typedef name 391 | // if there is no tag type name available 392 | if (RD->getIdentifier()) { 393 | // FIXME: We should not have to check for a null decl context here. 394 | // Right now we do it because the implicit Obj-C decls don't have one. 395 | - if (RD->getDeclContext()) 396 | - RD->printQualifiedName(OS); 397 | - else 398 | + if (RD->getDeclContext()) { 399 | + if (dyn_cast(RD)) { 400 | + TheCXXABI.getMangleContext().mangleCXXRTTI(Context.getTypeDeclType(RD), 401 | + OSR); 402 | + if (getContext().getSanitizerBlacklist().isBlacklistedType(OSR.str())) { 403 | + OS << "blacklistedtype" << '.'; 404 | + } else { 405 | + OS << "trackedtype" << '.'; 406 | + } 407 | + TheCXXABI.getMangleContext().mangleCXXRTTI(Context.getTypeDeclType(RD), 408 | + OS); 409 | + } 410 | + else { 411 | + OS << RD->getKindName() << '.'; 412 | + RD->printQualifiedName(OS); 413 | + } 414 | + } 415 | + else { 416 | + OS << RD->getKindName() << '.'; 417 | RD->printName(OS); 418 | + } 419 | } else if (const TypedefNameDecl *TDD = RD->getTypedefNameForAnonDecl()) { 420 | + OS << RD->getKindName() << '.'; 421 | // FIXME: We should not have to check for a null decl context here. 422 | // Right now we do it because the implicit Obj-C decls don't have one. 423 | if (TDD->getDeclContext()) 424 | TDD->printQualifiedName(OS); 425 | else 426 | TDD->printName(OS); 427 | - } else 428 | + } else { 429 | + OS << RD->getKindName() << '.'; 430 | OS << "anon"; 431 | + } 432 | 433 | if (!suffix.empty()) 434 | OS << suffix; 435 | diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp 436 | index e4e6c02..eed0ebb 100644 437 | --- a/lib/Driver/SanitizerArgs.cpp 438 | +++ b/lib/Driver/SanitizerArgs.cpp 439 | @@ -26,7 +26,7 @@ using namespace clang::driver; 440 | using namespace llvm::opt; 441 | 442 | enum : SanitizerMask { 443 | - NeedsUbsanRt = Undefined | Integer | CFI, 444 | + NeedsUbsanRt = Undefined | Integer | CFI | TypeSan , 445 | NeedsUbsanCxxRt = Vptr | CFI, 446 | NotAllowedWithTrap = Vptr, 447 | RequiresPIE = DataFlow, 448 | diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp 449 | index c1305f1..5aed078 100644 450 | --- a/lib/Driver/ToolChain.cpp 451 | +++ b/lib/Driver/ToolChain.cpp 452 | @@ -684,6 +684,8 @@ SanitizerMask ToolChain::getSupportedSanitizers() const { 453 | if (getTriple().getArch() == llvm::Triple::x86 || 454 | getTriple().getArch() == llvm::Triple::x86_64) 455 | Res |= CFIICall; 456 | + if (getTriple().getArch() == llvm::Triple::x86_64) 457 | + Res |= TypeSan; 458 | return Res; 459 | } 460 | 461 | diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp 462 | index 72e7caa..7933876 100644 463 | --- a/lib/Driver/Tools.cpp 464 | +++ b/lib/Driver/Tools.cpp 465 | @@ -2945,6 +2945,14 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, 466 | NonWholeStaticRuntimes.push_back("stats"); 467 | RequiredSymbols.push_back("__sanitizer_stats_register"); 468 | } 469 | + 470 | + if (SanArgs.needsTypeSanRt()) { 471 | + StaticRuntimes.push_back("typesan"); 472 | + } 473 | + 474 | + if (SanArgs.needsMetallocRt()) { 475 | + StaticRuntimes.push_back("metalloc"); 476 | + } 477 | } 478 | 479 | // Should be called before we add system libraries (C++ ABI, libstdc++/libc++, 480 | -------------------------------------------------------------------------------- /typesan/GPERFTOOLS_TYPESAN.patch: -------------------------------------------------------------------------------- 1 | From 7acd6447f93bff315360ab2180842fa3c5d929a2 Mon Sep 17 00:00:00 2001 2 | From: Istvan Haller 3 | Date: Fri, 13 May 2016 23:16:58 +0200 4 | Subject: [PATCH] Metalloc for type checking. 5 | 6 | --- 7 | Makefile.am | 13 +++-- 8 | src/central_freelist.cc | 28 +++++++++- 9 | src/common.cc | 14 +++++ 10 | src/common.h | 1 + 11 | src/malloc_hook_mmap_linux.h | 38 ++++++++++++++ 12 | src/tcmalloc.cc | 117 ++++++++++++++++++++++++++++++++++++++---- 13 | 6 files changed, 194 insertions(+), 17 deletions(-) 14 | 15 | diff --git a/Makefile.am b/Makefile.am 16 | index b5f4725..b3b4e76 100755 17 | --- a/Makefile.am 18 | +++ b/Makefile.am 19 | @@ -9,14 +9,14 @@ ACLOCAL_AMFLAGS = -I m4 20 | AUTOMAKE_OPTIONS = subdir-objects 21 | 22 | # This is so we can #include 23 | -AM_CPPFLAGS = -I$(top_srcdir)/src 24 | +AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/../metapagetable 25 | 26 | if !WITH_STACK_TRACE 27 | AM_CPPFLAGS += -DNO_TCMALLOC_SAMPLES 28 | endif !WITH_STACK_TRACE 29 | 30 | # This is mostly based on configure options 31 | -AM_CXXFLAGS = 32 | +AM_CXXFLAGS = -I$(top_srcdir)/../metapagetable 33 | 34 | NO_BUILTIN_CXXFLAGS = 35 | 36 | @@ -328,7 +328,8 @@ low_level_alloc_unittest_SOURCES = src/base/low_level_alloc.cc \ 37 | # By default, MallocHook takes stack traces for use by the heap-checker. 38 | # We don't need that functionality here, so we turn it off to reduce deps. 39 | low_level_alloc_unittest_CXXFLAGS = -DNO_TCMALLOC_SAMPLES 40 | -low_level_alloc_unittest_LDADD = $(LIBSPINLOCK) libmaybe_threads.la 41 | +low_level_alloc_unittest_LDADD = $(LIBSPINLOCK) libmaybe_threads.la $(top_srcdir)/../metapagetable/libmetapagetable.la 42 | +EXTRA_low_level_alloc_unittest_DEPENDENCIES = $(top_srcdir)/../metapagetable/libmetapagetable.la 43 | 44 | TESTS += atomicops_unittest 45 | ATOMICOPS_UNITTEST_INCLUDES = src/base/atomicops.h \ 46 | @@ -492,7 +493,8 @@ libtcmalloc_minimal_la_CXXFLAGS = -DNO_TCMALLOC_SAMPLES \ 47 | $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS) 48 | # -version-info gets passed to libtool 49 | libtcmalloc_minimal_la_LDFLAGS = -version-info @TCMALLOC_SO_VERSION@ $(AM_LDFLAGS) 50 | -libtcmalloc_minimal_la_LIBADD = libtcmalloc_minimal_internal.la 51 | +libtcmalloc_minimal_la_LIBADD = libtcmalloc_minimal_internal.la $(top_srcdir)/../metapagetable/libmetapagetable.la 52 | +EXTRA_libtcmalloc_minimal_la_DEPENDENCIES = $(top_srcdir)/../metapagetable/libmetapagetable.la 53 | 54 | # For windows, we're playing around with trying to do some stacktrace 55 | # support even with libtcmalloc_minimal. For everyone else, though, 56 | @@ -910,7 +912,8 @@ lib_LTLIBRARIES += libtcmalloc.la 57 | libtcmalloc_la_SOURCES = $(TCMALLOC_CC) $(TCMALLOC_INCLUDES) 58 | libtcmalloc_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS) 59 | libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@ 60 | -libtcmalloc_la_LIBADD = libtcmalloc_internal.la libmaybe_threads.la $(PTHREAD_LIBS) 61 | +libtcmalloc_la_LIBADD = libtcmalloc_internal.la libmaybe_threads.la $(PTHREAD_LIBS) $(top_srcdir)/../metapagetable/libmetapagetable.la 62 | +EXTRA_libtcmalloc_la_DEPENDENCIES = $(top_srcdir)/../metapagetable/libmetapagetable.la 63 | 64 | if WITH_HEAP_CHECKER 65 | # heap-checker-bcad is last, in hopes its global ctor will run first. 66 | diff --git a/src/central_freelist.cc b/src/central_freelist.cc 67 | index 11b190d..38541c4 100644 68 | --- a/src/central_freelist.cc 69 | +++ b/src/central_freelist.cc 70 | @@ -38,6 +38,7 @@ 71 | #include "linked_list.h" // for SLL_Next, SLL_Push, etc 72 | #include "page_heap.h" // for PageHeap 73 | #include "static_vars.h" // for Static 74 | +#include 75 | 76 | using std::min; 77 | using std::max; 78 | @@ -139,6 +140,14 @@ void CentralFreeList::ReleaseToSpans(void* object) { 79 | lock_.Unlock(); 80 | { 81 | SpinLockHolder h(Static::pageheap_lock()); 82 | + 83 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 84 | + unsigned long metaentry = get_metapagetable_entry((void*)(span->start << kPageShift)); 85 | + set_metapagetable_entries((void*)(span->start << kPageShift), span->length << kPageShift, 0, 0); 86 | + Span* metaspan = MapObjectToSpan((void*)(metaentry >> 8)); 87 | + Static::pageheap()->Delete(metaspan); 88 | + } 89 | + 90 | Static::pageheap()->Delete(span); 91 | } 92 | lock_.Lock(); 93 | @@ -327,7 +336,24 @@ void CentralFreeList::Populate() { 94 | { 95 | SpinLockHolder h(Static::pageheap_lock()); 96 | span = Static::pageheap()->New(npages); 97 | - if (span) Static::pageheap()->RegisterSizeClass(span, size_class_); 98 | + if (span) { 99 | + Static::pageheap()->RegisterSizeClass(span, size_class_); 100 | + 101 | + // Meta-pagetable might not be initialized yet. 102 | + page_table_init(); 103 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 104 | + int alignment = AlignmentBitsForSize(Static::sizemap()->ByteSizeForClass(size_class_)); 105 | + int rounding_offset = (1 << alignment) - 1; 106 | + Span* metaspan = Static::pageheap()->New((span->length * FLAGS_METALLOC_METADATABYTES + rounding_offset) >> alignment); 107 | + if (metaspan != NULL) { 108 | + set_metapagetable_entries((void*)(span->start << kPageShift), span->length << kPageShift, 109 | + (void*)(metaspan->start << kPageShift), alignment); 110 | + } else { 111 | + Static::pageheap()->Delete(span); 112 | + span = NULL; 113 | + } 114 | + } 115 | + } 116 | } 117 | if (span == NULL) { 118 | Log(kLog, __FILE__, __LINE__, 119 | diff --git a/src/common.cc b/src/common.cc 120 | index 2cf507e..fa2e106 100644 121 | --- a/src/common.cc 122 | +++ b/src/common.cc 123 | @@ -37,6 +37,7 @@ 124 | #include "system-alloc.h" 125 | #include "base/spinlock.h" 126 | #include "getenv_safe.h" // TCMallocGetenvSafe 127 | +#include 128 | 129 | namespace tcmalloc { 130 | 131 | @@ -96,6 +97,16 @@ int AlignmentForSize(size_t size) { 132 | return alignment; 133 | } 134 | 135 | +int AlignmentBitsForSize(size_t size) { 136 | + if (size > kMaxSize) { 137 | + // Cap alignment at kPageSize for large sizes. 138 | + return __builtin_ctzll(kPageSize); 139 | + } else { 140 | + // Return number of trailing 0-bits as alignment 141 | + return __builtin_ctzll(size); 142 | + } 143 | +} 144 | + 145 | int SizeMap::NumMoveSize(size_t size) { 146 | if (size == 0) return 0; 147 | // Use approx 64k transfers between thread and central caches. 148 | @@ -185,6 +196,9 @@ void SizeMap::Init() { 149 | for (int s = next_size; s <= max_size_in_class; s += kAlignment) { 150 | class_array_[ClassIndex(s)] = c; 151 | } 152 | + if (class_to_pages_[c] < 32) { 153 | + class_to_pages_[c] = 32; 154 | + } 155 | next_size = max_size_in_class + kAlignment; 156 | } 157 | 158 | diff --git a/src/common.h b/src/common.h 159 | index 15d7ee7..16ffbc7 100644 160 | --- a/src/common.h 161 | +++ b/src/common.h 162 | @@ -156,6 +156,7 @@ inline Length pages(size_t bytes) { 163 | // For larger allocation sizes, we use larger memory alignments to 164 | // reduce the number of size classes. 165 | int AlignmentForSize(size_t size); 166 | +int AlignmentBitsForSize(size_t size); 167 | 168 | // Size-class information + mapping 169 | class SizeMap { 170 | diff --git a/src/malloc_hook_mmap_linux.h b/src/malloc_hook_mmap_linux.h 171 | index 0f531db..906ccf2 100755 172 | --- a/src/malloc_hook_mmap_linux.h 173 | +++ b/src/malloc_hook_mmap_linux.h 174 | @@ -45,6 +45,7 @@ 175 | #include 176 | #include 177 | #include "base/linux_syscall_support.h" 178 | +#include 179 | 180 | // The x86-32 case and the x86-64 case differ: 181 | // 32b has a mmap2() syscall, 64b does not. 182 | @@ -121,6 +122,7 @@ static inline void* do_mmap64(void *start, size_t length, 183 | 184 | #endif // #if defined(__x86_64__) 185 | 186 | +void *metalloc_sentinel = 0; 187 | 188 | #ifdef MALLOC_HOOK_HAVE_DO_MMAP64 189 | 190 | @@ -161,6 +163,13 @@ extern "C" void* mmap64(void *start, size_t length, int prot, int flags, 191 | result = do_mmap64(start, length, prot, flags, fd, offset); 192 | } 193 | MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset); 194 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 195 | + if (metalloc_sentinel == 0) { 196 | + metalloc_sentinel = do_mmap64(0, METALLOC_PAGESIZE, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); 197 | + } 198 | + unsigned int rounded_length = (((length + METALLOC_PAGESIZE - 1) / METALLOC_PAGESIZE) * METALLOC_PAGESIZE); 199 | + set_metapagetable_entries(result, rounded_length, metalloc_sentinel, 63); 200 | + } 201 | return result; 202 | } 203 | 204 | @@ -176,6 +185,13 @@ extern "C" void* mmap(void *start, size_t length, int prot, int flags, 205 | static_cast(offset)); // avoid sign extension 206 | } 207 | MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset); 208 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 209 | + if (metalloc_sentinel == 0) { 210 | + metalloc_sentinel = do_mmap64(0, METALLOC_PAGESIZE, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); 211 | + } 212 | + unsigned int rounded_length = (((length + METALLOC_PAGESIZE - 1) / METALLOC_PAGESIZE) * METALLOC_PAGESIZE); 213 | + set_metapagetable_entries(result, rounded_length, metalloc_sentinel, 63); 214 | + } 215 | return result; 216 | } 217 | 218 | @@ -187,6 +203,10 @@ extern "C" int munmap(void* start, size_t length) __THROW { 219 | if (!MallocHook::InvokeMunmapReplacement(start, length, &result)) { 220 | result = sys_munmap(start, length); 221 | } 222 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 223 | + unsigned int rounded_length = (((length + METALLOC_PAGESIZE - 1) / METALLOC_PAGESIZE) * METALLOC_PAGESIZE); 224 | + set_metapagetable_entries(start, rounded_length, 0, 0); 225 | + } 226 | return result; 227 | } 228 | 229 | @@ -199,6 +219,17 @@ extern "C" void* mremap(void* old_addr, size_t old_size, size_t new_size, 230 | void* result = sys_mremap(old_addr, old_size, new_size, flags, new_address); 231 | MallocHook::InvokeMremapHook(result, old_addr, old_size, new_size, flags, 232 | new_address); 233 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 234 | + set_metapagetable_entries(old_addr, old_size, 0, 0); 235 | + if (metalloc_sentinel == 0) { 236 | + metalloc_sentinel = do_mmap64(0, METALLOC_PAGESIZE, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); 237 | + } 238 | + unsigned int rounded_length; 239 | + rounded_length = (((old_size + METALLOC_PAGESIZE - 1) / METALLOC_PAGESIZE) * METALLOC_PAGESIZE); 240 | + set_metapagetable_entries(old_addr, rounded_length, 0, 0); 241 | + rounded_length = (((new_size + METALLOC_PAGESIZE - 1) / METALLOC_PAGESIZE) * METALLOC_PAGESIZE); 242 | + set_metapagetable_entries(result, rounded_length, metalloc_sentinel, 63); 243 | + } 244 | return result; 245 | } 246 | 247 | @@ -210,6 +241,13 @@ extern "C" void* sbrk(ptrdiff_t increment) __THROW { 248 | MallocHook::InvokePreSbrkHook(increment); 249 | void *result = __sbrk(increment); 250 | MallocHook::InvokeSbrkHook(result, increment); 251 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 252 | + if (metalloc_sentinel == 0) { 253 | + metalloc_sentinel = do_mmap64(0, METALLOC_PAGESIZE, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); 254 | + } 255 | + unsigned int rounded_length = (((increment + METALLOC_PAGESIZE - 1) / METALLOC_PAGESIZE) * METALLOC_PAGESIZE); 256 | + set_metapagetable_entries(result, rounded_length, metalloc_sentinel, 63); 257 | + } 258 | return result; 259 | } 260 | 261 | diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc 262 | index 387ba76..939d853 100644 263 | --- a/src/tcmalloc.cc 264 | +++ b/src/tcmalloc.cc 265 | @@ -131,6 +131,7 @@ 266 | #include "system-alloc.h" // for DumpSystemAllocatorStats, etc 267 | #include "tcmalloc_guard.h" // for TCMallocGuard 268 | #include "thread_cache.h" // for ThreadCache 269 | +#include 270 | 271 | #ifdef __clang__ 272 | // clang's apparent focus on code size somehow causes it to ignore 273 | @@ -1139,8 +1140,24 @@ inline bool should_report_large(Length num_pages) { 274 | return false; 275 | } 276 | 277 | +static ALWAYS_INLINE void* clear_metadata_ptr(void *ptr, size_t size) { 278 | + unsigned long page = (unsigned long)ptr / METALLOC_PAGESIZE; 279 | + unsigned long entry = pageTable[page]; 280 | + unsigned long alignment = entry & 0xFF; 281 | + char *metabase = (char*)(entry >> 8); 282 | + unsigned long *metaptr = (unsigned long*)(metabase + ((((unsigned long)ptr - (page * METALLOC_PAGESIZE)) >> alignment) * FLAGS_METALLOC_METADATABYTES)); 283 | + void *result = (void*)(*metaptr); 284 | + if (result != 0) { 285 | + unsigned long metasize = (FLAGS_METALLOC_METADATABYTES / 8) * ((size + (1 << (alignment)) - 1) >> alignment); 286 | + for (unsigned long i = 0; i < metasize; ++i) { 287 | + metaptr[i] = 0; 288 | + } 289 | + } 290 | + return result; 291 | +} 292 | + 293 | // Helper for do_malloc(). 294 | -inline void* do_malloc_pages(ThreadCache* heap, size_t size) { 295 | +inline void* do_malloc_pages(ThreadCache* heap, size_t &size) { 296 | void* result; 297 | bool report_large; 298 | 299 | @@ -1155,6 +1172,22 @@ inline void* do_malloc_pages(ThreadCache* heap, size_t size) { 300 | } else { 301 | SpinLockHolder h(Static::pageheap_lock()); 302 | Span* span = Static::pageheap()->New(num_pages); 303 | + 304 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 305 | + if (span != NULL) { 306 | + int alignment = kPageShift; 307 | + int rounding_offset = (1 << alignment) - 1; 308 | + Span* metaspan = Static::pageheap()->New((span->length * FLAGS_METALLOC_METADATABYTES + rounding_offset) >> alignment); 309 | + if (metaspan != 0) { 310 | + set_metapagetable_entries((void*)(span->start << kPageShift), span->length << kPageShift, 311 | + (void*)(metaspan->start << kPageShift), alignment); 312 | + } else { 313 | + Static::pageheap()->Delete(span); 314 | + span = NULL; 315 | + } 316 | + } 317 | + } 318 | + 319 | result = (UNLIKELY(span == NULL) ? NULL : SpanToMallocResult(span)); 320 | report_large = should_report_large(num_pages); 321 | } 322 | @@ -1165,9 +1198,10 @@ inline void* do_malloc_pages(ThreadCache* heap, size_t size) { 323 | return result; 324 | } 325 | 326 | -ALWAYS_INLINE void* do_malloc_small(ThreadCache* heap, size_t size) { 327 | +ALWAYS_INLINE void* do_malloc_small(ThreadCache* heap, size_t &size) { 328 | ASSERT(Static::IsInited()); 329 | ASSERT(heap != NULL); 330 | + 331 | size_t cl = Static::sizemap()->SizeClass(size); 332 | size = Static::sizemap()->class_to_size(cl); 333 | 334 | @@ -1181,14 +1215,21 @@ ALWAYS_INLINE void* do_malloc_small(ThreadCache* heap, size_t size) { 335 | } 336 | 337 | ALWAYS_INLINE void* do_malloc(size_t size) { 338 | + void *result; 339 | + bool doNotClear = size & ((size_t)1 << (sizeof(size_t) * 8 - 1)); 340 | + size &= ((size_t)1 << (sizeof(size_t) * 8 - 1)) - 1; 341 | if (ThreadCache::have_tls && 342 | LIKELY(size < ThreadCache::MinSizeForSlowPath())) { 343 | - return do_malloc_small(ThreadCache::GetCacheWhichMustBePresent(), size); 344 | + result = do_malloc_small(ThreadCache::GetCacheWhichMustBePresent(), size); 345 | } else if (size <= kMaxSize) { 346 | - return do_malloc_small(ThreadCache::GetCache(), size); 347 | + result = do_malloc_small(ThreadCache::GetCache(), size); 348 | } else { 349 | - return do_malloc_pages(ThreadCache::GetCache(), size); 350 | + result = do_malloc_pages(ThreadCache::GetCache(), size); 351 | } 352 | + if (!doNotClear) { 353 | + clear_metadata_ptr(result, size); 354 | + } 355 | + return result; 356 | } 357 | 358 | static void *retry_malloc(void* size) { 359 | @@ -1205,11 +1246,13 @@ ALWAYS_INLINE void* do_malloc_or_cpp_alloc(size_t size) { 360 | } 361 | 362 | ALWAYS_INLINE void* do_calloc(size_t n, size_t elem_size) { 363 | + size_t doNotClearFlag = elem_size & ((size_t)1 << (sizeof(size_t) * 8 - 1)); 364 | + elem_size &= ((size_t)1 << (sizeof(size_t) * 8 - 1)) - 1; 365 | // Overflow check 366 | - const size_t size = n * elem_size; 367 | + const size_t size = (n * elem_size); 368 | if (elem_size != 0 && size / elem_size != n) return NULL; 369 | 370 | - void* result = do_malloc_or_cpp_alloc(size); 371 | + void* result = do_malloc_or_cpp_alloc(size | doNotClearFlag); 372 | if (result != NULL) { 373 | if (size <= kMaxSize) 374 | memset(result, 0, size); 375 | @@ -1271,6 +1314,7 @@ ALWAYS_INLINE void do_free_helper(void* ptr, 376 | Static::pageheap()->CacheSizeClass(p, cl); 377 | } 378 | ASSERT(ptr != NULL); 379 | + 380 | if (LIKELY(cl != 0)) { 381 | ASSERT(!Static::pageheap()->GetDescriptor(p)->sample); 382 | if (heap_must_be_valid || heap != NULL) { 383 | @@ -1290,6 +1334,15 @@ ALWAYS_INLINE void do_free_helper(void* ptr, 384 | Static::stacktrace_allocator()->Delete(st); 385 | span->objects = NULL; 386 | } 387 | + 388 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 389 | + unsigned long metaentry = get_metapagetable_entry((void*)(span->start << kPageShift)); 390 | + set_metapagetable_entries((void*)(span->start << kPageShift), span->length << kPageShift, 0, 0); 391 | + const PageID metapage = (metaentry >> 8) >> kPageShift; 392 | + Span* metaspan = Static::pageheap()->GetDescriptor(metapage); 393 | + Static::pageheap()->Delete(metaspan); 394 | + } 395 | + 396 | Static::pageheap()->Delete(span); 397 | } 398 | } 399 | @@ -1346,6 +1399,8 @@ ALWAYS_INLINE void* do_realloc_with_callback( 400 | void* old_ptr, size_t new_size, 401 | void (*invalid_free_fn)(void*), 402 | size_t (*invalid_get_size_fn)(const void*)) { 403 | + size_t doNotClearFlag = new_size & ((size_t)1 << (sizeof(size_t) * 8 - 1)); 404 | + new_size &= ((size_t)1 << (sizeof(size_t) * 8 - 1)) - 1; 405 | // Get the size of the old entry 406 | const size_t old_size = GetSizeWithCallback(old_ptr, invalid_get_size_fn); 407 | 408 | @@ -1362,11 +1417,11 @@ ALWAYS_INLINE void* do_realloc_with_callback( 409 | void* new_ptr = NULL; 410 | 411 | if (new_size > old_size && new_size < lower_bound_to_grow) { 412 | - new_ptr = do_malloc_or_cpp_alloc(lower_bound_to_grow); 413 | + new_ptr = do_malloc_or_cpp_alloc(lower_bound_to_grow | doNotClearFlag); 414 | } 415 | if (new_ptr == NULL) { 416 | // Either new_size is not a tiny increment, or last do_malloc failed. 417 | - new_ptr = do_malloc_or_cpp_alloc(new_size); 418 | + new_ptr = do_malloc_or_cpp_alloc(new_size | doNotClearFlag); 419 | } 420 | if (UNLIKELY(new_ptr == NULL)) { 421 | return NULL; 422 | @@ -1402,11 +1457,15 @@ ALWAYS_INLINE void* do_realloc(void* old_ptr, size_t new_size) { 423 | void* do_memalign(size_t align, size_t size) { 424 | ASSERT((align & (align - 1)) == 0); 425 | ASSERT(align > 0); 426 | + 427 | + size_t doNotClearFlag = size & ((size_t)1 << (sizeof(size_t) * 8 - 1)); 428 | + size &= ((size_t)1 << (sizeof(size_t) * 8 - 1)) - 1; 429 | + 430 | if (size + align < size) return NULL; // Overflow 431 | 432 | // Fall back to malloc if we would already align this memory access properly. 433 | if (align <= AlignmentForSize(size)) { 434 | - void* p = do_malloc(size); 435 | + void* p = do_malloc(size | doNotClearFlag); 436 | ASSERT((reinterpret_cast(p) % align) == 0); 437 | return p; 438 | } 439 | @@ -1431,7 +1490,11 @@ void* do_memalign(size_t align, size_t size) { 440 | if (cl < kNumClasses) { 441 | ThreadCache* heap = ThreadCache::GetCache(); 442 | size = Static::sizemap()->class_to_size(cl); 443 | - return CheckedMallocResult(heap->Allocate(size, cl)); 444 | + void *result = CheckedMallocResult(heap->Allocate(size, cl)); 445 | + if (!doNotClearFlag) { 446 | + clear_metadata_ptr(result, size); 447 | + } 448 | + return result; 449 | } 450 | } 451 | 452 | @@ -1443,6 +1506,22 @@ void* do_memalign(size_t align, size_t size) { 453 | // TODO: We could put the rest of this page in the appropriate 454 | // TODO: cache but it does not seem worth it. 455 | Span* span = Static::pageheap()->New(tcmalloc::pages(size)); 456 | + 457 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 458 | + if (span != NULL) { 459 | + int alignment = kPageShift; 460 | + int rounding_offset = (1 << alignment) - 1; 461 | + Span* metaspan = Static::pageheap()->New((span->length * FLAGS_METALLOC_METADATABYTES + rounding_offset) >> alignment); 462 | + if (metaspan != 0) { 463 | + set_metapagetable_entries((void*)(span->start << kPageShift), span->length << kPageShift, 464 | + (void*)(metaspan->start << kPageShift), alignment); 465 | + } else { 466 | + Static::pageheap()->Delete(span); 467 | + span = NULL; 468 | + } 469 | + } 470 | + } 471 | + 472 | return UNLIKELY(span == NULL) ? NULL : SpanToMallocResult(span); 473 | } 474 | 475 | @@ -1470,6 +1549,22 @@ void* do_memalign(size_t align, size_t size) { 476 | Span* trailer = Static::pageheap()->Split(span, needed); 477 | Static::pageheap()->Delete(trailer); 478 | } 479 | + 480 | + if (!FLAGS_METALLOC_FIXEDCOMPRESSION) { 481 | + if (span != NULL) { 482 | + int alignment = kPageShift; 483 | + int rounding_offset = (1 << alignment) - 1; 484 | + Span* metaspan = Static::pageheap()->New((span->length * FLAGS_METALLOC_METADATABYTES + rounding_offset) >> alignment); 485 | + if (metaspan != 0) { 486 | + set_metapagetable_entries((void*)(span->start << kPageShift), span->length << kPageShift, 487 | + (void*)(metaspan->start << kPageShift), alignment); 488 | + } else { 489 | + Static::pageheap()->Delete(span); 490 | + span = NULL; 491 | + } 492 | + } 493 | + } 494 | + 495 | return SpanToMallocResult(span); 496 | } 497 | 498 | -- 499 | 1.7.9.5 500 | 501 | -------------------------------------------------------------------------------- /lowfat/config/lowfat-config.c: -------------------------------------------------------------------------------- 1 | /* 2 | * _| _|_|_|_| _| 3 | * _| _|_| _| _| _| _| _|_|_| _|_|_|_| 4 | * _| _| _| _| _| _| _|_|_| _| _| _| 5 | * _| _| _| _| _| _| _| _| _| _| _| 6 | * _|_|_|_| _|_| _| _| _| _|_|_| _|_| 7 | * 8 | * Gregory J. Duck. 9 | * 10 | * Copyright (c) 2017 The National University of Singapore. 11 | * All rights reserved. 12 | * 13 | * This file is distributed under the University of Illinois Open Source 14 | * License. See the LICENSE file for details. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include 30 | 31 | #define PAGE_SIZE 4096 32 | #define MIN_SIZES 8 33 | #define MAX_SIZES 4096 34 | #define MIN_SIZE 16 35 | #define MIN_REGION_SIZE 16 36 | #define MAX_REGION_SIZE 1024 37 | #define MB 0x100000ul 38 | #define GB 0x40000000ul 39 | #define MAX(a, b) ((a) > (b)? (a): (b)) 40 | #define MIN(a, b) ((a) > (b)? (b): (a)) 41 | #define STACK_SIZE (64 * MB) 42 | #define MAX_STACK_ALLOC (STACK_SIZE / 2) 43 | #define MAX_GLOBAL_ALLOC (64 * MB) 44 | #define ASLR_MASK 0xFFFFFFFF 45 | #define LOWFAT_SIZES 0x200000 46 | #define LOWFAT_MAGICS 0x300000 47 | #define CPUID(a, c, ax, bx, cx, dx) \ 48 | __asm__ __volatile__ ("cpuid" : "=a" (ax), "=b" (bx), "=c" (cx), \ 49 | "=d" (dx) : "a" (a), "c" (c)) 50 | 51 | #define REGION(idx, size) ((void *)(((idx)+1)*(size))) 52 | 53 | static bool is_pow2(size_t x) 54 | { 55 | return ((x & (x - 1)) == 0); 56 | } 57 | 58 | static inline uintptr_t base(uintptr_t ptr, size_t size, size_t magic) 59 | { 60 | return (uintptr_t)(((__int128)ptr * (__int128)magic) >> 64) * size; 61 | } 62 | 63 | static int clzll(uint64_t x) 64 | { 65 | if (x == 0) 66 | return 64; 67 | uint64_t bit = (uint64_t)1 << 63; 68 | int count = 0; 69 | while ((x & bit) == 0) 70 | { 71 | count++; 72 | bit >>= 1; 73 | } 74 | return count; 75 | } 76 | 77 | struct error_info 78 | { 79 | pthread_mutex_t *lock; 80 | size_t *sizes; 81 | size_t *magics; 82 | size_t *errors; 83 | size_t sizes_len; 84 | size_t region_size; 85 | }; 86 | 87 | /* 88 | * Calculate precision errors. See: 89 | * "Heap Bounds Protection with Low Fat Pointers", Section 5.1.1 90 | */ 91 | static void *error_worker(void *arg) 92 | { 93 | struct error_info *info = (struct error_info *)arg; 94 | pthread_mutex_t *lock = info->lock; 95 | size_t *sizes = info->sizes; 96 | size_t *magics = info->magics; 97 | size_t *errors = info->errors; 98 | size_t sizes_len = info->sizes_len; 99 | size_t region_size = info->region_size; 100 | free(info); 101 | 102 | pthread_mutex_lock(lock); 103 | for (size_t i = 0; i < sizes_len; i++) 104 | { 105 | if (errors[i] != SIZE_MAX) 106 | continue; 107 | errors[i] = 0; 108 | 109 | // Check for cached value: 110 | FILE *stream = fopen("lowfat.errs", "r"); 111 | if (stream != NULL) 112 | { 113 | uintptr_t region_start = (i + 1) * region_size; 114 | void *ptr; 115 | size_t region_size0, size, error; 116 | bool found = false; 117 | while (fscanf(stream, "%p %zu %zu %zu", &ptr, ®ion_size0, 118 | &size, &error) == 4) 119 | { 120 | if (region_size0 == region_size && size == sizes[i] && 121 | ptr == (void *)region_start) 122 | { 123 | found = true; 124 | break; 125 | } 126 | } 127 | fclose(stream); 128 | if (found) 129 | { 130 | errors[i] = error; 131 | continue; 132 | } 133 | } 134 | 135 | pthread_mutex_unlock(lock); 136 | 137 | size_t size = sizes[i]; 138 | size_t magic = magics[i]; 139 | uintptr_t region_start = (i + 1) * region_size; 140 | uintptr_t region_end = region_start + region_size; 141 | region_start = region_start - (region_start % size); 142 | size_t error = 0; 143 | for (uintptr_t ptr = region_start; ptr <= region_end; ptr += size) 144 | { 145 | size_t lo = 0, hi = size; 146 | while (lo <= hi) 147 | { 148 | size_t mid = (lo + hi) / 2; 149 | uintptr_t bptr = base(ptr + mid, size, magic); 150 | if (bptr != ptr) 151 | hi = mid-1; 152 | else 153 | lo = mid+1; 154 | } 155 | error = MAX(size - lo, error); 156 | } 157 | errors[i] = error; 158 | pthread_mutex_lock(lock); 159 | 160 | // Write value to cache: 161 | stream = fopen("lowfat.errs", "a"); 162 | if (stream != NULL) 163 | { 164 | region_start = (i + 1) * region_size; 165 | fprintf(stream, "%p %zu %zu %zu\n", (void *)region_start, 166 | region_size, size, error); 167 | fclose(stream); 168 | } 169 | } 170 | pthread_mutex_unlock(lock); 171 | 172 | return NULL; 173 | } 174 | 175 | static void spawn_error_worker(pthread_t *thread, pthread_mutex_t *lock, 176 | size_t *sizes, size_t *magics, size_t *errors, size_t sizes_len, 177 | size_t region_size) 178 | { 179 | struct error_info *info = (struct error_info *)malloc( 180 | sizeof(struct error_info)); 181 | if (info == NULL) 182 | { 183 | fprintf(stderr, "error: failed to allocate memory: %s\n", 184 | strerror(errno)); 185 | exit(EXIT_FAILURE); 186 | } 187 | info->lock = lock; 188 | info->sizes = sizes; 189 | info->magics = magics; 190 | info->errors = errors; 191 | info->sizes_len = sizes_len; 192 | info->region_size = region_size; 193 | int r = pthread_create(thread, NULL, error_worker, info); 194 | if (r < 0) 195 | { 196 | fprintf(stderr, "error: failed to spawn error worker: %s\n", 197 | strerror(errno)); 198 | exit(EXIT_FAILURE); 199 | } 200 | } 201 | 202 | static void compile(FILE *stream, FILE *hdr_stream, FILE *ld_stream, 203 | size_t *sizes, size_t *magics, size_t *errors, size_t region_size, 204 | size_t sizes_len, bool pow2, bool legacy); 205 | 206 | #define OPTION_NO_ERROR_GEN 1 207 | #define OPTION_NO_MEMORY_ALIAS 2 208 | #define OPTION_NO_REPLACE_STD_MALLOC 3 209 | #define OPTION_NO_STD_MALLOC_FALLBACK 4 210 | #define OPTION_NO_THREADS 5 211 | 212 | static bool option_no_error_gen = false; 213 | static bool option_no_memory_alias = false; 214 | static bool option_no_std_malloc_fallback = false; 215 | static bool option_no_replace_std_malloc = false; 216 | static bool option_no_threads = false; 217 | 218 | /* 219 | * Main. 220 | */ 221 | int main(int argc, char **argv) 222 | { 223 | static struct option long_options[] = 224 | { 225 | {"no-error-gen", 0, 0, OPTION_NO_ERROR_GEN}, 226 | {"no-memory-alias", 0, 0, OPTION_NO_MEMORY_ALIAS}, 227 | {"no-replace-std-malloc", 0, 0, OPTION_NO_REPLACE_STD_MALLOC}, 228 | {"no-std-malloc-fallback", 0, 0, OPTION_NO_STD_MALLOC_FALLBACK}, 229 | {"no-threads", 0, 0, OPTION_NO_THREADS}, 230 | {NULL, 0, 0, 0} 231 | }; 232 | while (true) 233 | { 234 | int idx; 235 | int opt = getopt_long(argc, argv, "", long_options, &idx); 236 | if (opt < 0) 237 | break; 238 | switch (opt) 239 | { 240 | case OPTION_NO_ERROR_GEN: 241 | option_no_error_gen = true; 242 | break; 243 | case OPTION_NO_MEMORY_ALIAS: 244 | option_no_memory_alias = true; 245 | break; 246 | case OPTION_NO_STD_MALLOC_FALLBACK: 247 | option_no_std_malloc_fallback = true; 248 | break; 249 | case OPTION_NO_REPLACE_STD_MALLOC: 250 | option_no_replace_std_malloc = true; 251 | break; 252 | case OPTION_NO_THREADS: 253 | option_no_threads = true; 254 | break; 255 | default: 256 | usage: 257 | fprintf(stderr, "usage: %s [OPTIONS] sizes.cfg " 258 | "region-size\n\n", argv[0]); 259 | fprintf(stderr, "Where OPTIONS are:\n"); 260 | fprintf(stderr, "\t--no-error-gen\n"); 261 | fprintf(stderr, "\t\tSkip error generation (may produce " 262 | "invalid results).\n"); 263 | fprintf(stderr, "\t--no-memory-alias\n"); 264 | fprintf(stderr, "\t\tDo not use memory aliasing for the " 265 | "stack.\n"); 266 | fprintf(stderr, "\t--no-replace-std-malloc\n"); 267 | fprintf(stderr, "\t\tDo not replace stdlib malloc() with " 268 | "low-fat malloc() in\n"); 269 | fprintf(stderr, "\t\tuninstrumented (linked) code. NOTE: " 270 | "stdlib malloc() will\n"); 271 | fprintf(stderr, "\t\tstill be replaced in instrumented " 272 | "code.\n"); 273 | fprintf(stderr, "\t--no-std-malloc-fallback\n"); 274 | fprintf(stderr, "\t\tNever fallback to stdlib malloc() if " 275 | "low-fat malloc() fails.\n"); 276 | fprintf(stderr, "\t--no-threads\n"); 277 | fprintf(stderr, "\t\tDo not support multi-threaded " 278 | "programs.\n"); 279 | return EXIT_FAILURE; 280 | } 281 | } 282 | if (optind != argc-2) 283 | goto usage; 284 | 285 | printf( 286 | "_| _|_|_|_| _|\n" 287 | "_| _|_| _| _| _| _| _|_|_| _|_|_|_|\n" 288 | "_| _| _| _| _| _| _|_|_| _| _| _|\n" 289 | "_| _| _| _| _| _| _| _| _| _| _|\n" 290 | "_|_|_|_| _|_| _| _| _| _|_|_| _|_|\n" 291 | "\n"); 292 | 293 | size_t region_size = atoi(argv[optind+1]); 294 | if (region_size < MIN_REGION_SIZE || region_size > MAX_REGION_SIZE) 295 | { 296 | fprintf(stderr, "error: region size must be within range %u..%uGB\n", 297 | MIN_REGION_SIZE, MAX_REGION_SIZE); 298 | return EXIT_FAILURE; 299 | } 300 | if (!is_pow2(region_size)) 301 | { 302 | fprintf(stderr, "error: region size must be a power-of-two\n"); 303 | return EXIT_FAILURE; 304 | } 305 | region_size *= GB; 306 | size_t MAX_SIZE = region_size / 4; 307 | 308 | if (PAGE_SIZE != getpagesize()) 309 | { 310 | fprintf(stderr, "error: page size mis-match (expected %u, got %d)\n", 311 | PAGE_SIZE, getpagesize()); 312 | return EXIT_FAILURE; 313 | } 314 | 315 | size_t sizes[MAX_SIZES]; 316 | const char *filename = argv[optind]; 317 | printf("Parsing \"%s\"...\n", filename); 318 | FILE *stream = fopen(filename, "r"); 319 | if (stream == NULL) 320 | { 321 | fprintf(stderr, "error: failed to open file \"%s\": %s\n", filename, 322 | strerror(errno)); 323 | return EXIT_FAILURE; 324 | } 325 | size_t i; 326 | for (i = 0; i < MAX_SIZES; i++) 327 | { 328 | if (fscanf(stream, "%zu", sizes+i) != 1) 329 | { 330 | if (ferror(stream)) 331 | { 332 | read_error: 333 | fprintf(stderr, "error: failed to read file \"%s\": %s\n", 334 | filename, strerror(errno)); 335 | return EXIT_FAILURE; 336 | } 337 | break; 338 | } 339 | if (sizes[i] > MAX_SIZE) 340 | break; 341 | if (sizes[i] < MIN_SIZE || sizes[i] % MIN_SIZE != 0) 342 | { 343 | fprintf(stderr, "error: size %zu from size configuration file " 344 | "\"%s\" is invalid (min=%u, max=%zu, multiple-of-%u)\n", 345 | sizes[i], filename, MIN_SIZE, MAX_SIZE, MIN_SIZE); 346 | return EXIT_FAILURE; 347 | } 348 | if (i == 0 && sizes[i] != MIN_SIZE) 349 | { 350 | fprintf(stderr, "error: size for region #0 must be %u\n", 351 | MIN_SIZE); 352 | return EXIT_FAILURE; 353 | } 354 | if (i > 0 && sizes[i] <= sizes[i-1]) 355 | { 356 | fprintf(stderr, "error: size configuration file \"%s\" is not " 357 | "ascending (%zu <= %zu)\n", filename, sizes[i], sizes[i-1]); 358 | return EXIT_FAILURE; 359 | } 360 | } 361 | fclose(stream); 362 | if (i <= MIN_SIZES || i >= MAX_SIZES) 363 | { 364 | fprintf(stderr, "error: size configuration file \"%s\" length " 365 | "out-of-range (min=%u, max=%u)\n", filename, MIN_SIZES+1, 366 | MAX_SIZES-1); 367 | return EXIT_FAILURE; 368 | } 369 | size_t sizes_len = i; 370 | 371 | // Check for LZCNT/BMI support: 372 | bool legacy = false; 373 | uint32_t eax, ebx, ecx, edx; 374 | CPUID(7, 0, eax, ebx, ecx, edx); 375 | if (((ebx >> 3) & 1) == 0 || ((ebx >> 8) & 1) == 0) 376 | legacy = true; 377 | 378 | // Check for power-of-two sizes: 379 | bool ispow2 = true; 380 | for (size_t i = 0; i < sizes_len; i++) 381 | { 382 | if (!is_pow2(sizes[i])) 383 | { 384 | ispow2 = false; 385 | break; 386 | } 387 | } 388 | printf("IsPow2=%s\n", (ispow2? "true": "false")); 389 | 390 | // Calculate magic numbers: 391 | size_t magics[sizes_len]; 392 | if (!ispow2) 393 | { 394 | for (size_t i = 0; i < sizes_len; i++) 395 | { 396 | __int128 r = UINT64_MAX; 397 | r++; 398 | magics[i] = (size_t)(r / (__int128)sizes[i]) + 1; 399 | printf("Region #%zu: size=%zu magic=0x%.16zX\n", i+1, sizes[i], 400 | magics[i]); 401 | } 402 | } 403 | else 404 | { 405 | for (size_t i = 0; i < sizes_len; i++) 406 | { 407 | magics[i] = UINT64_MAX << (unsigned)log2((double)sizes[i]); 408 | printf("Region #%zu: size=%zu magic=0x%.16zX\n", i+1, sizes[i], 409 | magics[i]); 410 | } 411 | } 412 | 413 | // Calculate errors: 414 | size_t errors[sizes_len]; 415 | memset(errors, 0, sizeof(errors)); 416 | if (!option_no_error_gen && !ispow2) 417 | { 418 | printf("Calculating errors (this may take some time)...\n"); 419 | unsigned NUM_WORKERS = (unsigned)sysconf(_SC_NPROCESSORS_ONLN); 420 | pthread_t workers[NUM_WORKERS]; 421 | pthread_mutex_t lock; 422 | pthread_mutex_init(&lock, NULL); 423 | for (size_t i = 0; i < sizes_len; i++) 424 | errors[i] = SIZE_MAX; 425 | for (size_t i = 0; i < NUM_WORKERS; i++) 426 | spawn_error_worker(workers+i, &lock, sizes, magics, errors, 427 | sizes_len, region_size); 428 | for (size_t i = 0; i < NUM_WORKERS; i++) 429 | pthread_join(workers[i], NULL); 430 | for (size_t i = 0; i < sizes_len; i++) 431 | printf("Region #%zu: error=%zuB\n", i+1, errors[i]); 432 | } 433 | 434 | // Generate files: 435 | filename = "lowfat_config.c"; 436 | printf("Generating \"%s\"...\n", filename); 437 | stream = fopen(filename, "w"); 438 | if (stream == NULL) 439 | { 440 | fprintf(stderr, "error: failed to open file \"%s\": %s\n", filename, 441 | strerror(errno)); 442 | return EXIT_FAILURE; 443 | } 444 | filename = "lowfat_config.h"; 445 | FILE *hdr_stream = fopen(filename, "w"); 446 | if (hdr_stream == NULL) 447 | { 448 | fprintf(stderr, "error: failed to open file \"%s\": %s\n", filename, 449 | strerror(errno)); 450 | return EXIT_FAILURE; 451 | } 452 | filename = "lowfat.ld"; 453 | FILE *ld_stream = fopen(filename, "w"); 454 | if (stream == NULL) 455 | { 456 | fprintf(stderr, "error: failed to open file \"%s\": %s\n", filename, 457 | strerror(errno)); 458 | return EXIT_FAILURE; 459 | } 460 | compile(stream, hdr_stream, ld_stream, sizes, magics, errors, 461 | region_size, sizes_len, ispow2, legacy); 462 | fclose(stream); 463 | fclose(hdr_stream); 464 | fclose(ld_stream); 465 | 466 | printf("Done...\n"); 467 | return 0; 468 | } 469 | 470 | static size_t stack_select(size_t *sizes, size_t sizes_len, size_t size) 471 | { 472 | if (size > MAX_STACK_ALLOC) 473 | return sizes_len; 474 | for (size_t i = 0; i < sizes_len; i++) 475 | { 476 | if (!is_pow2(sizes[i])) 477 | continue; 478 | if (size <= sizes[i]) 479 | return i; 480 | } 481 | return sizes_len; 482 | } 483 | 484 | /* 485 | * Output the low-fat-pointer configuration for the given parameters. 486 | */ 487 | static void compile(FILE *stream, FILE *hdr_stream, FILE *ld_stream, 488 | size_t *sizes, size_t *magics, size_t *errors, size_t region_size, 489 | size_t sizes_len, bool pow2, bool legacy) 490 | { 491 | /* 492 | * Region layout: 493 | * +------------------------------+----+----+---------+ 494 | * | H | G1 | G2 | S | 495 | * +------------------------------+----+----+---------+ 496 | * 497 | * H = Heap memory 498 | * G1 = Global memory (non-const) (2GB) 499 | * G2 = Global memory (const) (2GB) 500 | * S = Stack memory (4GB) 501 | */ 502 | size_t H_G1_GAP_SIZE = 8*PAGE_SIZE; 503 | size_t G1_G2_GAP_SIZE = 0; 504 | size_t G2_S_GAP_SIZE = 8*PAGE_SIZE; 505 | size_t S_SIZE = 4*GB; 506 | size_t G1_SIZE = 8*GB; 507 | size_t G2_SIZE = 8*GB; 508 | size_t H_SIZE = region_size - H_G1_GAP_SIZE - G1_SIZE - G1_G2_GAP_SIZE - 509 | G2_SIZE - G2_S_GAP_SIZE - S_SIZE; 510 | size_t H_OFFSET = 0; 511 | size_t G_FUDGE = PAGE_SIZE; 512 | size_t G1_OFFSET = H_OFFSET + H_SIZE + H_G1_GAP_SIZE - G_FUDGE; 513 | size_t G2_OFFSET = G1_OFFSET + G1_SIZE + G1_G2_GAP_SIZE; 514 | size_t S_OFFSET = G2_OFFSET + G2_SIZE + G2_S_GAP_SIZE + G_FUDGE; 515 | 516 | size_t stack_region = sizes_len+1; 517 | 518 | if (hdr_stream != NULL) 519 | { 520 | fprintf(hdr_stream, "/* AUTOMATICALLY GENERATED */\n"); 521 | fprintf(hdr_stream, "#ifndef __LOWFAT_CONFIG_H\n"); 522 | fprintf(hdr_stream, "#define __LOWFAT_CONFIG_H\n"); 523 | fprintf(hdr_stream, "\n"); 524 | fprintf(hdr_stream, "#define _LOWFAT_SIZES ((size_t *)0x%X)\n", 525 | LOWFAT_SIZES); 526 | fprintf(hdr_stream, "#define _LOWFAT_MAGICS ((uint64_t *)0x%X)\n", 527 | LOWFAT_MAGICS); 528 | fprintf(hdr_stream, "#define _LOWFAT_REGION_SIZE %zuull\n", 529 | region_size); 530 | if (legacy) 531 | fprintf(hdr_stream, "#define _LOWFAT_LEGACY 1\n"); 532 | fprintf(hdr_stream, "\n"); 533 | fprintf(hdr_stream, "#endif\t/* __LOWFAT_CONFIG_H */\n"); 534 | } 535 | 536 | if (ld_stream != NULL) 537 | { 538 | fprintf(ld_stream, "/* AUTOMATICALLY GENERATED */\n"); 539 | fprintf(ld_stream, "\n"); 540 | fprintf(ld_stream, "SECTIONS\n"); 541 | fprintf(ld_stream, "{\n"); 542 | for (size_t i = 0; i < sizes_len; i++) 543 | { 544 | if (sizes[i] >= MAX_GLOBAL_ALLOC) 545 | break; 546 | if (!is_pow2(sizes[i])) 547 | continue; 548 | void *start = REGION(i, region_size) + G1_OFFSET; 549 | fprintf(ld_stream, "\t. = %p + SIZEOF_HEADERS;\n", start); 550 | fprintf(ld_stream, "\tlowfat_section_%zu :\n", sizes[i]); 551 | fprintf(ld_stream, "\t{\n"); 552 | fprintf(ld_stream, "\t\tKEEP(*(lowfat_section_%zu))\n", sizes[i]); 553 | fprintf(ld_stream, "\t}\n"); 554 | void *end = start + G1_SIZE; 555 | fprintf(ld_stream, "\tASSERT(. < %p, \"Lowfat section " 556 | "(lowfat_section_%zu) is too big; max size is 2GB\")\n", 557 | end, sizes[i]); 558 | start = REGION(i, region_size) + G2_OFFSET; 559 | fprintf(ld_stream, "\t. = %p + SIZEOF_HEADERS;\n", start); 560 | fprintf(ld_stream, "\tlowfat_section_const_%zu :\n", sizes[i]); 561 | fprintf(ld_stream, "\t{\n"); 562 | fprintf(ld_stream, "\t\tKEEP(*(lowfat_section_const_%zu))\n", 563 | sizes[i]); 564 | fprintf(ld_stream, "\t}\n"); 565 | end = start + G1_SIZE; 566 | fprintf(ld_stream, "\tASSERT(. < %p, \"Lowfat section " 567 | "(lowfat_const_section_%zu) is too big; max size is 2GB\")\n", 568 | end, sizes[i]); 569 | } 570 | const size_t data_buffer = 32; // 32 regions 571 | void *data_start = REGION(sizes_len + data_buffer, region_size); 572 | fprintf(ld_stream, "\t. = %p + SIZEOF_HEADERS;\n", data_start); 573 | fprintf(ld_stream, "\tLOWFAT_DATA :\n"); 574 | fprintf(ld_stream, "\t{\n"); 575 | fprintf(ld_stream, "\t\tKEEP(*(LOWFAT_DATA))\n"); 576 | fprintf(ld_stream, "\t}\n"); 577 | void *const_data_start = REGION(sizes_len + data_buffer + 1, 578 | region_size); 579 | fprintf(ld_stream, "\t. = %p + SIZEOF_HEADERS;\n", const_data_start); 580 | fprintf(ld_stream, "\tLOWFAT_CONST_DATA :\n"); 581 | fprintf(ld_stream, "\t{\n"); 582 | fprintf(ld_stream, "\t\tKEEP(*(LOWFAT_CONST_DATA))\n"); 583 | fprintf(ld_stream, "\t}\n"); 584 | fprintf(ld_stream, "}\n"); 585 | fprintf(ld_stream, "\n"); 586 | fprintf(ld_stream, "INSERT AFTER .gnu.attributes;\n"); 587 | fprintf(ld_stream, "\n"); 588 | } 589 | 590 | fprintf(stream, "/* AUTOMATICALLY GENERATED */\n"); 591 | fprintf(stream, "\n"); 592 | fprintf(stream, "#include \"lowfat_config.h\"\n"); 593 | fprintf(stream, "\n"); 594 | if (pow2) 595 | fprintf(stream, "#define LOWFAT_IS_POW2 1\n"); 596 | fprintf(stream, "#define LOWFAT_NUM_REGIONS %zu\n", sizes_len); 597 | size_t num_pages = (sizes_len * sizeof(size_t) - 1) / PAGE_SIZE + 1; 598 | fprintf(stream, "#define LOWFAT_SIZES_PAGES %zu\n", num_pages); 599 | fprintf(stream, "#define LOWFAT_REGION_SIZE _LOWFAT_REGION_SIZE\n"); 600 | size_t region_shift = (size_t)log2((double)region_size); 601 | fprintf(stream, "#define LOWFAT_REGION_SIZE_SHIFT %zu\n", region_shift); 602 | fprintf(stream, "#define LOWFAT_STACK_MEMORY_SIZE %zu\n", S_SIZE); 603 | fprintf(stream, "#define LOWFAT_GLOBAL_MEMORY_SIZE %zu\n", 604 | G1_SIZE + G2_SIZE); 605 | fprintf(stream, "#define LOWFAT_HEAP_MEMORY_SIZE %zu\n", H_SIZE); 606 | fprintf(stream, "#define LOWFAT_STACK_MEMORY_OFFSET %zu\n", S_OFFSET); 607 | fprintf(stream, "#define LOWFAT_GLOBAL_MEMORY_OFFSET %zu\n", G1_OFFSET); 608 | fprintf(stream, "#define LOWFAT_HEAP_MEMORY_OFFSET %zu\n", H_OFFSET); 609 | size_t stack_size = STACK_SIZE; 610 | fprintf(stream, "#define LOWFAT_STACK_SIZE %zu\n", stack_size); 611 | fprintf(stream, "#define LOWFAT_PAGE_SIZE %u\n", PAGE_SIZE); 612 | fprintf(stream, "#define LOWFAT_HEAP_ASLR_MASK 0x%.8Xull\n", 613 | ASLR_MASK); 614 | fprintf(stream, "#define LOWFAT_MAX_HEAP_ALLOC_SIZE %zu\n", 615 | sizes[sizes_len-1]); 616 | fprintf(stream, "#define LOWFAT_TID_OFFSET 0x%x\n", 0x2d0); 617 | fprintf(stream, "#define LOWFAT_JOINID_OFFSET 0x%x\n", 0x628); 618 | if (option_no_memory_alias) 619 | fprintf(stream, "#define LOWFAT_NO_MEMORY_ALIAS 1\n"); 620 | if (option_no_std_malloc_fallback) 621 | fprintf(stream, "#define LOWFAT_NO_STD_MALLOC_FALLBACK 1\n"); 622 | if (option_no_replace_std_malloc) 623 | fprintf(stream, "#define LOWFAT_NO_REPLACE_STD_MALLOC 1\n"); 624 | if (option_no_threads) 625 | fprintf(stream, "#define LOWFAT_NO_THREADS 1\n"); 626 | if (legacy) 627 | fprintf(stream, "#define LOWFAT_LEGACY 1\n"); 628 | size_t max_stack_alloc = MAX_STACK_ALLOC; 629 | size_t max_stack_region; 630 | bool found = false; 631 | for (ssize_t i = sizes_len-1; i >= 0; i--) 632 | { 633 | if (i == 0 || (is_pow2(sizes[i]) && max_stack_alloc == sizes[i])) 634 | { 635 | found = true; 636 | max_stack_region = i+1; 637 | break; 638 | } 639 | } 640 | if (!found) 641 | { 642 | fprintf(stderr, "error: max stack allocation size (%zu) not found in " 643 | "size configuration\n", max_stack_alloc); 644 | exit(EXIT_FAILURE); 645 | } 646 | fprintf(stream, "#define LOWFAT_MAX_STACK_ALLOC_SIZE %zu\n", 647 | max_stack_alloc); 648 | fprintf(stream, "#define LOWFAT_MAX_GLOBAL_ALLOC_SIZE %zu\n", 649 | MAX_GLOBAL_ALLOC); 650 | fprintf(stream, "#define LOWFAT_MIN_ALLOC_SIZE %u\n", MIN_SIZE); 651 | fprintf(stream, "#define LOWFAT_NUM_STACK_REGIONS %zu\n", 652 | max_stack_region); 653 | fprintf(stream, "#define LOWFAT_STACK_REGION %zu\n", stack_region); 654 | fprintf(stream, "#define LOWFAT_CONST_DATA " 655 | "__attribute__((__section__(\"LOWFAT_CONST_DATA\")))\n"); 656 | fprintf(stream, "\n"); 657 | 658 | // lowfat_sizes 659 | fprintf(stream, "static const LOWFAT_CONST_DATA size_t " 660 | "lowfat_sizes[] =\n"); 661 | fprintf(stream, "{\n"); 662 | for (size_t i = 0; i < sizes_len; i++) 663 | fprintf(stream, "\t%zu, /* idx=%zu */\n", sizes[i], i); 664 | fprintf(stream, "};\n"); 665 | fprintf(stream, "\n"); 666 | 667 | // lowfat_magics 668 | fprintf(stream, "static const LOWFAT_CONST_DATA size_t " 669 | "lowfat_magics[] =\n"); 670 | fprintf(stream, "{\n"); 671 | for (size_t i = 0; i < sizes_len; i++) 672 | fprintf(stream, "\t0x%.16zXull, /* idx=%zu, size=%zu */\n", magics[i], 673 | i, sizes[i]); 674 | fprintf(stream, "};\n"); 675 | fprintf(stream, "\n"); 676 | 677 | // lowfat_stacks 678 | fprintf(stream, "static const LOWFAT_CONST_DATA size_t " 679 | "lowfat_stacks[] =\n"); 680 | fprintf(stream, "{\n"); 681 | for (size_t i = 0; i < sizes_len; i++) 682 | { 683 | if (!is_pow2(sizes[i])) 684 | continue; 685 | if (sizes[i] > max_stack_alloc) 686 | continue; 687 | fprintf(stream, "\t%zu,\n", i+1); 688 | } 689 | fprintf(stream, "\t%zu,\n", stack_region); 690 | fprintf(stream, "\t0,\n"); 691 | fprintf(stream, "};\n"); 692 | fprintf(stream, "\n"); 693 | 694 | // lowfat_stack_indexes 695 | fprintf(stream, "const LOWFAT_CONST_DATA size_t " 696 | "lowfat_stack_sizes[64+1] =\n"); 697 | fprintf(stream, "{\n"); 698 | for (size_t i = 0; i < 65; i++) 699 | { 700 | size_t max_size = (i >= 64? 0: SIZE_MAX >> i); 701 | size_t idx = stack_select(sizes, sizes_len, max_size); 702 | if (idx == sizes_len) 703 | fprintf(stream, "\t0, /* idx=%zu */\n", i); 704 | else 705 | fprintf(stream, "\t%zu, /* idx=%zu */\n", sizes[idx], i); 706 | } 707 | fprintf(stream, "};\n"); 708 | fprintf(stream, "\n"); 709 | 710 | // lowfat_stack_masks 711 | fprintf(stream, "const LOWFAT_CONST_DATA size_t " 712 | "lowfat_stack_masks[64+1] =\n"); 713 | fprintf(stream, "{\n"); 714 | for (size_t i = 0; i < 65; i++) 715 | { 716 | size_t max_size = (i >= 64? 0: SIZE_MAX >> i); 717 | size_t idx = stack_select(sizes, sizes_len, max_size); 718 | if (idx == sizes_len) 719 | fprintf(stream, "\t0, /* idx=%zu */\n", i); 720 | else 721 | { 722 | size_t size = sizes[idx]; 723 | size_t mask = ~(size - 1); 724 | fprintf(stream, "\t0x%.16zXull,\t/* idx=%zu, size=%zu */\n", mask, 725 | i, size); 726 | } 727 | } 728 | fprintf(stream, "};\n"); 729 | fprintf(stream, "\n"); 730 | 731 | // lowfat_stack_offsets 732 | fprintf(stream, "const LOWFAT_CONST_DATA ssize_t " 733 | "lowfat_stack_offsets[64+1] =\n"); 734 | fprintf(stream, "{\n"); 735 | for (size_t i = 0; i < 65; i++) 736 | { 737 | size_t max_size = (i >= 64? 0: SIZE_MAX >> i); 738 | size_t idx = stack_select(sizes, sizes_len, max_size); 739 | if (idx == sizes_len) 740 | fprintf(stream, "\t0, /* idx=%zu */\n", i); 741 | else 742 | { 743 | ssize_t diff = ((ssize_t)idx - (ssize_t)sizes_len) * region_size; 744 | fprintf(stream, "\t%zd,\t/* idx=%zu, size=%zu */\n", diff, i, 745 | sizes[idx]); 746 | } 747 | } 748 | fprintf(stream, "};\n"); 749 | fprintf(stream, "\n"); 750 | 751 | // lowfat_heap_select 752 | fprintf(stream, "static size_t lowfat_heap_select(size_t size)\n"); 753 | fprintf(stream, "{\n"); 754 | if (legacy) 755 | { 756 | fprintf(stream, "\tif (size == 0)\n"); 757 | fprintf(stream, "\t\treturn 1;\n"); 758 | } 759 | fprintf(stream, "\tswitch (__builtin_clzll(size))\n"); 760 | fprintf(stream, "\t{\n"); 761 | fprintf(stream, "\t\tcase 64:\n"); 762 | for (ssize_t i = 64-1; i >= 0; i--) 763 | { 764 | fprintf(stream, "\t\tcase %zu:\n", i); 765 | for (size_t j = 0; j < sizes_len; j++) 766 | { 767 | size_t size = sizes[j]; 768 | if (clzll(size) == i) 769 | { 770 | fprintf(stream, "\t\t\tif (size <= %zu-1-%zu)\n", size, 771 | errors[j]); 772 | size_t idx = j+1; 773 | fprintf(stream, "\t\t\t\treturn %zu;\n", idx); 774 | } 775 | } 776 | } 777 | fprintf(stream, "\t\tdefault:\n"); 778 | fprintf(stream, "\t\t\treturn 0;\n"); 779 | fprintf(stream, "\t}\n"); 780 | fprintf(stream, "}\n"); 781 | fprintf(stream, "\n"); 782 | } 783 | 784 | --------------------------------------------------------------------------------