Package: razor
DescriptionOCCAMis a whole-program partial evaluator for LLVM bitcode that aims at debloating programs and shared/static libraries running in a specific deployment context.OCCAM architectureDockerA pre-built and installed version of OCCAM can be obtained using Docker:dockerpullsricsl/occam:bionic
dockerrun-v`pwd`:/host-itsricsl/occam:bionicAlternatively, it can be built and installed from source as follows.PrerequisitesOCCAM currently works on Linux, macOS, and FreeBSD.  It depends on an installation of LLVM. OCCAM currently is built on the top of llvm-10.0 which requires a C++ compiler supporting c++14. You will also need the Google protocol buffer compilerprotocand the corresponding Pythonpackage. Some OCCAM components (such assea-dsaandcrabrequire the boost library >= 1.65.If you need to generate application bitcode (that OCCAM operates on), you will want to install WLLVM, either from the the pippackageor the GitHubrepository.The test harness also requireslitandFileCheck.FileCheckcan often be found in the binary directory of your LLVM installation. However, if you built your own, you may need to readthis.Hint: the build produces it, but does not install it. (Trylocate FileCheck, then copy it to thebindirectory.)Detailed configuration instructions for Ubuntu 18.04 can be gleaned frombootstrap.shas well as the Travis CI scripts for each branch.travis.yml.Building and InstallingSet where OCCAM's library will be stored:export OCCAM_HOME={path to location in your home directory}Point to your LLVM's location, if non-standard:export LLVM_HOME=/usr/local/llvm-10.0
  export LLVM_CONFIG=llvm-config-10.0Set where system libraries, including Google Protocol Buffers, are located:export LD_FLAGS='-L/usr/local/lib'Clone, build, and install OCCAM with:git clone --recurse-submodules https://github.com/SRI-CSL/OCCAM.git
  make
  make install
  make testUsing OCCAMYou can choose to record logs from OCCAM by setting the following variables:export OCCAM_LOGFILE={absolute path to log location}
  export OCCAM_LOGLEVEL={INFO, WARNING, or ERROR}Using razorrazoris a pip package that relies on the same dynamic library asoccam. So you should first build and installoccamas described above.razorprovides the commandline toolslashfor end users. You can either installrazorfrom this repository, or you can use:pip install razorTo install an editable version from this repository:make -f Makefile developThis may require sudo privileges. Either way you can now useslash:slash [--work-dir=<dir>]  [--force] [--no-strip] [--intra-spec-policy=<type>] [--inter-spec-policy=<type>] [--use-pointer-analysis] [--enable-config-prime] <manifest>wheretype=none|aggressive|nonrec-aggressive|bounded|onlyonceThe valuenonewill prevent any inter or intra-module specialization. The valueaggressivespecializes a call if any parameter is a constant. The valuenonrec-aggressivespecializes a call if the function is non-recursive and any parameter is a constant. The valueboundedmakes at mostkcopies wherekcan be chosen by option--max-bounded-spec. The valueonlyoncemakes a copy of a function only if the function is called exactly once.To function correctlyslashcalls LLVM tools such asoptandclang++. These should be available in yourPATH, and be the currently supported version (10.0). Likewllvm,slash, will pay attention to the environment variablesLLVM_OPT_NAMEandLLVM_CXX_NAMEif your version of these tools is adorned with suffixes.The ManifestThe manifest forslashshould be valid JSON. The following keys have meaning:main: a path to the bitcode module containing themainentry point.modules: a list of paths to the other bitcode modules needed.binary: the name of the desired executable.native_libs: a list of flags (-lm,-lc,-lpthread) or paths to native objects (.o,.a,.so,.dylib)ldflags: a list of linker flags such as--static,--nostdlibname: the program namestatic_args: the list of static arguments you wish to specialize in themain()ofmain.dynamic_args: a number that indicates the arguments the specialized program will receive at runtime. If this key is omitted then the default value is 0 which means that the specialized program does not expect any parameter.lib_spec: list of library bitcode you wish to specialize with respect tomainor a list ofmainfunctions given bymain_spec.main_spec:  list of bitcode modules each containing amainfunction used bylib_spec.As an example, (seeexamples/linux/apache), to previrtualize apache:{ "main" : "httpd.bc"
, "binary" : "httpd_slashed"
, "modules" : ["libapr-1.so.bc", "libaprutil-1.so.bc", "libpcre.so.bc"]
, "native_libs" : ["-lcrypt", "-ldl", "-lpthread"]
, "name"    : "httpd"
, "static_args" : ["-d", "/var/www"]
}Another example, (seeexamples/linux/musl_nweb), specializesnwebwithmusl libc.c:{ "main" :  "nweb.o.bc"
, "binary" : "nweb_razor"
, "modules" : ["libc.a.bc"]
, "native_libs" : ["crt1.o", "libc.a"]
, "ldflags" : ["-static", "-nostdlib"]
, "name" : "nweb"
, "static_args" : ["8181", "./root"]
, "dynamic_args" : "0"
}A third example, (seeexamples/linux/tree),  illustrates the use of thedynamic_argsfield to partially specialize the arguments to thetreeutility.{ "main" : "tree.bc"
, "binary"  : "tree"
, "modules"    : []
, "native_libs" : []
, "ldflags" : [ "-O2" ]
, "name"    : "tree"
, "static_args" : ["-J", "-h"]
, "dynamic_args" : "1"
}The specialized program will output its results in JSON notation (-J) that will include a human readable size field (-h). The specialized program expects one extra argument, either a directory or another flag to output the contents of the current working directory.This material is based upon work supported by the National Science Foundation under GrantACI-1440800. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.