Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -167,6 +167,8 @@ HelpText<"Turn off Type Based Alias Analysis">; def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">, HelpText<"Turn off struct-path aware Type Based Alias Analysis">; +def nop_insertion : Flag<["-"], "nop-insertion">, + HelpText<"Randomly insert NOPs">; def masm_verbose : Flag<["-"], "masm-verbose">, HelpText<"Generate verbose assembly output">; def mcode_model : Separate<["-"], "mcode-model">, Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -436,6 +436,7 @@ def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">, Group, Flags<[CC1Option]>, HelpText<"Print a template comparison tree for differing templates">; +def fdiversify : Flag<["-"], "fdiversify">, Group; def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group, HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>; def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group; @@ -765,7 +766,7 @@ def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group; def fprofile_generate : Flag<["-"], "fprofile-generate">, Group; def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>; -def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group; +def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group, Flags<[CC1Option]>; def freg_struct_return : Flag<["-"], "freg-struct-return">, Group, Flags<[CC1Option]>, HelpText<"Override the default ABI to return small structs in registers">; def frtti : Flag<["-"], "frtti">, Group; Index: include/clang/Frontend/CodeGenOptions.h =================================================================== --- include/clang/Frontend/CodeGenOptions.h +++ include/clang/Frontend/CodeGenOptions.h @@ -119,6 +119,9 @@ /// file, for example with -save-temps. std::string MainFileName; + /// Random seed used for the random number generator + uint64_t RandomSeed; + /// The name for the split debug info file that we'll break out. This is used /// in the backend for setting the name in the skeleton cu. std::string SplitDwarfFile; Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -155,6 +155,8 @@ CODEGENOPT(SanitizeRecover, 1, 1) ///< Attempt to recover from sanitizer checks ///< by continuing execution when possible +CODEGENOPT(NOPInsertion, 1, 0) ///< Randomly add NOPs + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -492,6 +492,7 @@ Options.TrapFuncName = CodeGenOpts.TrapFuncName; Options.PositionIndependentExecutable = LangOpts.PIELevel != 0; Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks; + Options.NOPInsertion = CodeGenOpts.NOPInsertion; TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, Options, Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -3391,6 +3391,20 @@ } } + // Translate -frandom-seed to seed the LLVM RNG + if (Args.hasArg(options::OPT_frandom_seed_EQ)) { + StringRef seed = Args.getLastArgValue(options::OPT_frandom_seed_EQ); + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back(Args.MakeArgString("-rng-seed=" + seed)); + } + + if (Args.hasArg(options::OPT_fdiversify)) { + CmdArgs.push_back("-nop-insertion"); + + CmdArgs.push_back("-backend-option"); + CmdArgs.push_back("-sched-randomize"); + } + if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it, options::OPT_mno_restrict_it)) { if (A->getOption().matches(options::OPT_mrestrict_it)) { Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -32,6 +32,7 @@ #include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" +#include "llvm/Support/RandomNumberGenerator.h" #include "llvm/Support/system_error.h" #include #include @@ -458,6 +459,8 @@ Opts.SSPBufferSize = getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); + Opts.NOPInsertion = Args.hasArg(OPT_nop_insertion); + if (Arg *A = Args.getLastArg(OPT_mstack_alignment)) { StringRef Val = A->getValue(); unsigned StackAlignment = Opts.StackAlignment; @@ -1670,6 +1673,16 @@ Opts.Triple = llvm::sys::getDefaultTargetTriple(); } +static void SaltRNG(ArgList &Args) { + std::vector Inputs = Args.getAllArgValues(OPT_INPUT); + std::string SaltString; + for (std::vector::iterator I = Inputs.begin(), E = Inputs.end(); + I != E; ++I) { + SaltString += *I; + } + llvm::RandomNumberGenerator::SetSalt(SaltString); +} + bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, const char *const *ArgBegin, const char *const *ArgEnd, @@ -1724,6 +1737,8 @@ ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, FileMgr, Diags); ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args, Res.getFrontendOpts().ProgramAction); + SaltRNG(*Args); + return Success; }