NOTE: This page is still work in progress. Static rooting analysis should probably be integrated better in our build process which should make it easier to use. [[TOC]] == Overview The static rooting analysis uses a GCC plugin to dump possible callstacks that can cause GC and statically (at compile time) analyses this data for rooting hazards. The main differences to dynamic rooting analysis are: * Covers all compiled code at once during compile time. There's no need to actually execute these codepaths in the game. * Setup is more complicated * Only covers stack based rooting * There can be false positives == Requirements * Sixgill plugin: [http://people.mozilla.org/~sfink/data/hazards-sixgill.tar.xz hazards-sixgill.tar.xz] * GCC version compatible with sixgill plugin: [http://people.mozilla.org/~sfink/data/hazards-gcc4.7.tar.xz hazards-gcc4.7.tar.xz] Download the sixgill plugin and extract it where you like. This path will be called "/path/to/sixgill". Download the custom GCC and extract it where you like. This path will be called "/path/to/customgcc". == Setup === Generating .xdb files The first step is to generate the .xdb files that contain all the information generated at compile time. You need to combine the information from the SpiderMonkey build and the 0 A.D. build. 1. Open a terminal 1. Set environment PATH and GCCDIR environment variables: {{{ PATH=/path/to/sixgill/usr/bin:$PATH export PATH GCCDIR=/path/to/customgcc/bin export GCCDIR }}} 1. Change to the SpiderMonkey source directory and call configure. In my case I had to set the system's default include paths and library search paths because the custom GCC was compiled for another system with different include paths. The rest are just the normal flags and they aren't related to the static analysis (may be different in your case). {{{ cd 0ad/libraries/spidermonkey yves@yves-desktop:~/Projekte/0ad/libraries/source/spidermonkey/mozjs-38.0.0/js/src/build-release$ CFLAGS="-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu" CXXFLAGS="-B/usr/lib/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu" ../configure --enable-shared-js --disable-tests --enable-valgrind --with-nspr-libs="-lplds4 -lplc4 -lnspr4" --with-nspr-cflags="-I/usr/include/nspr" --enable-optimize --without-intl-api }}} 1. Build SpiderMonkey {{{ yves@yves-desktop:~/Projekte/0ad/libraries/source/spidermonkey/mozjs-38.0.0/js/src/build-release$ ../devtools/rootAnalysis/run_complete --build-root=/home/yves/Projekte/0ad/libraries/source/spidermonkey/mozjs38/js/src/build-release --binaries=/path/to/sixgill/usr/bin --wrap-dir=/path/to/sixgill/usr/libexec/sixgill/scripts/wrap_gcc --buildcommand='make' --foreground . }}} 1. There should be 5 .xdb files in libraries/source/spidermonkey/mozjs-38.0.0/js/src/build-release. Copy them to build/workspaces/gcc. 1. Build 0 A.D. {{{ yves@yves-desktop:~/Projekte/0ad/build/workspaces/gcc$ perl ../../../libraries/source/spidermonkey/mozjs-38.0.0/js/src/devtools/rootAnalysis/run_complete --build-root=/home/yves/Projekte/0ad/build/workspaces/gcc --binaries=/path/to/sixgill/usr/bin --wrap-dir=/path/to/sixgill/usr/libexec/sixgill/scripts/wrap_gcc --buildcommand='CXXFLAGS="-I/usr/include/x86_64-linux-gnu" make pyrogenesis' --foreground . }}} 1. After the build is completed, the .xdb files in 0ad/build/workspaces/gcc should contain the information from the SpiderMonkey build and the 0 A.D. build. ==== Troubleshooting The following logfiles are generated when running run_complete with the correct GCC and an active sixgill plugin. You can also pass --no-logs to run_complete, which will print the logs in the console directly (except basecc.log). || '''File''' || '''Path''' || '''Description''' || || basecc.log || /tmp || || || build_xgill.log || the path specified by --build-root || || || build.log || the path specified by --build-root || || || build_err.log || the path specified by --build-root || || || build_manager.log || the path specified by --build-root || || || complete.log || the path specified by --build-root || || === Analyzing .xdb files The second step is to run a series of scripts on the .xdb files generated in the previous step. 1. Create a directory that will contain the output files of the analysis. This directory will be called "/path/to/analyzedir". 1. Copy the .xdb files from 0ad/build/workspaces/gcc to /path/to/analyzedir. 1. WORKAROUND: Change line 123 in mozjs-38.0.0/js/src/devtools/rootAnalysis/analyzeRoots.js from "assert(false);" to "return false;". 1. Run the analyze script. {{{ @yves-desktop:~/Projekte/analyze_hazards$ python /home/yves/Projekte/0ad/libraries/source/spidermonkey/mozjs-38.0.0/js/src/devtools/rootAnalysis/analyze.py callgraph }}} You can restart analyze.py at any point. Pass --list to show the different stages, and use one of those in place of 'callgraph'. By default, it'll go from the stage you request all the way to the end. ==== Troubleshooting .xdb files are key value pairs. You can use the tools in /path/to/sixgill/usr/bin to inspect the data they contain. || '''Command''' || '''Description''' || '''Example''' || || xdbfind || Search and print value by key || xdbfind -plain-text something.xdb keyname || || xdbkeys || List all keys || xdbkeys something.xdb || == Reading the output AnalyzeRoots.js will generate the following files. Examples are attached to this wiki page. '''hazards.txt''' This file contains callstacks that are quite likely to be rooting hazards. It might contain false positives too. ''' refs.txt ''' This file lists places where you take the address of an unrooted value. The analysis can't tell for sure if that's a hazard or not, so this file has a much higher false positive rate than hazards.txt.