The details : I wanted to add an option -random-stack-layout which would set a global option variable that I could read to turn on/off my stack layout randomization code in PrologEpilogInserter.cpp.
Before I talk about the changes, let me give you a quick introduction to how clang works. clang can work in the 'driver' mode and in the 'cc1' mode. The following command-line output, generated using the -v option, shows how this works.
km:~/projects/llvm-obj/Debug$ ./bin/clang -v ~/test/llvm/stack.c -o st
clang version 2.8 (tags/RELEASE_28)
Target: i386-pc-linux-gnu
Thread model: posix
"/home/km/projects/llvm-obj/Debug/bin/clang" -cc1 -triple i386-pc-linux-gnu -S -disable-free -disable-llvm-verifier -main-file-name stack.c -mrelocation-model static - mdisable-fp-elim -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.20.1 -v -resource-dir /home/km/projects/llvm-obj/Debug/lib/clang/2.8 -ferror-limit 19 -fmessage-length 237 -fgnu-runtime -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/cc-uTVPpH.s -x c /home/km/test/llvm/stack.c
clang -cc1 version 2.8 based upon llvm 2.8 hosted on i386-pc-linux-gnu
............
.............
"/usr/bin/as" --32 -o /tmp/cc-cFqgsc.o /tmp/cc-uTVPpH.s
"/usr/bin/gcc" -v -m32 -o st /tmp/cc-cFqgsc.o
when clang is invoked in the driver mode it invokes itself again with a list of arguments. The -cc1 is the argument that makes it behave like a compiler. This makes clang produce a .s file from the input .c file and then as, and gcc are invoked to produce the final executable (st in this example).
Note how the -v option is passed to gcc also. This is because -v is parsed and interpreted by the driver-mode clang. To avoid this behavior, the -Xclang switch can be used to send arguments to only cc1-mode clang.
The following changes illustrate the necessary changes to add an option that can be passed in with the -Xclang switch :
- Edit /llvm/tools/clang/include/clang/Driver/CC1Options.td to add your option string under the appropriate section. In my case, I wanted to add a CodeGen option so I added the following line under the CodeGen options section.
def random_stack_layout : Flag<"-random-stack-layout">,
HelpText<"Enables stack layout randomization">;
- The option variable to set/unset is multicompiler::RandomStackLayout. It is an unsigned integer that is declared in/llvm/include/llvm/MultiCompiler/MultiCompilerOptions.h, and is defined in/llvm/lib/CodeGen/MultiCompilerOptions.cpp that gets compiled into the CodeGen library.
- The OPT_ random_stack_layout flag can be checked in the ParseCodeGenArgs() method in /llvm/tools/clang/lib/Frontend/CompilerInvocation.cpp
#include "llvm/MultiCompiler/MultiCompilerOptions.h"
..........
...........
static void ParseCodeGenArgs( ...) {
.........
.........
multicompiler::RandomStackLayout = Args.hasArg(OPT_random_stack_layout);
..........
}
- The RandomStackLayout variable can now be accessed in any CodeGen file by including the MultiCompilerOptions.h header file. The option can be specified in the command line as shown below
./bin/clang -Xclang -random-stack-layout ~/test/llvm/stack.c -o st