From e0cfd8aae3595513576ea442d0975bd6803f575c Mon Sep 17 00:00:00 2001 From: James Foster Date: Sat, 23 Feb 2019 00:37:29 +0000 Subject: [PATCH 1/8] Added basic implementation of auto selection for strucutres of only function pointers --- .../clang/AST/RecordFieldReorganizer.h | 1 + clang/lib/AST/RecordFieldReorganizer.cpp | 21 +++++++++++++++++-- clang/lib/AST/RecordLayoutBuilder.cpp | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/AST/RecordFieldReorganizer.h b/clang/include/clang/AST/RecordFieldReorganizer.h index 1f2562b5e389c..7f15e1b3b10ed 100644 --- a/clang/include/clang/AST/RecordFieldReorganizer.h +++ b/clang/include/clang/AST/RecordFieldReorganizer.h @@ -34,6 +34,7 @@ class RecordFieldReorganizer { private: void commit(const RecordDecl *D, SmallVectorImpl &NewFieldOrder) const; + bool autostructselect(const SmallVector fields) const; }; class Randstruct : public RecordFieldReorganizer { diff --git a/clang/lib/AST/RecordFieldReorganizer.cpp b/clang/lib/AST/RecordFieldReorganizer.cpp index 4a4d8c60e55d9..0190acd50c922 100644 --- a/clang/lib/AST/RecordFieldReorganizer.cpp +++ b/clang/lib/AST/RecordFieldReorganizer.cpp @@ -35,7 +35,11 @@ void RecordFieldReorganizer::reorganizeFields(const ASTContext &C, mutateGuard.insert(f); fields.push_back(f); } - + if(D->getAttr() == nullptr){ + if(!autostructselect(fields)){ + return; + } + } // Now allow subclass implementations to reorder the fields reorganize(C, D, fields); @@ -50,7 +54,20 @@ void RecordFieldReorganizer::reorganizeFields(const ASTContext &C, commit(D, fields); } - +bool RecordFieldReorganizer::autostructselect(const SmallVector fields) const { + + bool Select = true; + for (auto f : fields){ + auto t = f->getFunctionType(); + auto s = ((FieldDecl *)f)->getNameAsString(); + llvm::errs() << "Function " << s << " type: " << t << "\n"; + if(t == nullptr){ + Select = false; + break; + } + } + return Select; +} void RecordFieldReorganizer::commit( const RecordDecl *D, SmallVectorImpl &NewFieldOrder) const { Decl *First, *Last; diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 6c69b91ef75e2..8f8b3671214b3 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2988,7 +2988,7 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { const ASTRecordLayout *NewEntry = nullptr; bool ShouldBeRandomized = D->getAttr() != nullptr; - if (ShouldBeRandomized) { + if (true) { Randstruct randstruct; randstruct.reorganizeFields(*this, D); } From 6fedc9d410abe42998bc1e9a29ded0cd8663be11 Mon Sep 17 00:00:00 2001 From: James Foster Date: Tue, 26 Feb 2019 03:48:56 +0000 Subject: [PATCH 2/8] Refactored the auto selection code --- .../clang/AST/RecordFieldReorganizer.h | 2 ++ clang/lib/AST/RecordFieldReorganizer.cpp | 26 +++++-------------- clang/lib/AST/RecordLayoutBuilder.cpp | 9 +++---- 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/AST/RecordFieldReorganizer.h b/clang/include/clang/AST/RecordFieldReorganizer.h index 7f15e1b3b10ed..494cfa9433c02 100644 --- a/clang/include/clang/AST/RecordFieldReorganizer.h +++ b/clang/include/clang/AST/RecordFieldReorganizer.h @@ -38,6 +38,8 @@ class RecordFieldReorganizer { }; class Randstruct : public RecordFieldReorganizer { +public: + bool isTriviallyRandomizable(const RecordDecl *D) const; protected: virtual void reorganize(const ASTContext &C, const RecordDecl *D, SmallVector &NewOrder) const override; diff --git a/clang/lib/AST/RecordFieldReorganizer.cpp b/clang/lib/AST/RecordFieldReorganizer.cpp index 0190acd50c922..f02f0fe849c6c 100644 --- a/clang/lib/AST/RecordFieldReorganizer.cpp +++ b/clang/lib/AST/RecordFieldReorganizer.cpp @@ -35,11 +35,6 @@ void RecordFieldReorganizer::reorganizeFields(const ASTContext &C, mutateGuard.insert(f); fields.push_back(f); } - if(D->getAttr() == nullptr){ - if(!autostructselect(fields)){ - return; - } - } // Now allow subclass implementations to reorder the fields reorganize(C, D, fields); @@ -54,20 +49,6 @@ void RecordFieldReorganizer::reorganizeFields(const ASTContext &C, commit(D, fields); } -bool RecordFieldReorganizer::autostructselect(const SmallVector fields) const { - - bool Select = true; - for (auto f : fields){ - auto t = f->getFunctionType(); - auto s = ((FieldDecl *)f)->getNameAsString(); - llvm::errs() << "Function " << s << " type: " << t << "\n"; - if(t == nullptr){ - Select = false; - break; - } - } - return Select; -} void RecordFieldReorganizer::commit( const RecordDecl *D, SmallVectorImpl &NewFieldOrder) const { Decl *First, *Last; @@ -266,5 +247,10 @@ void Randstruct::reorganize(const ASTContext &C, const RecordDecl *D, SmallVector randomized = perfrandomize(C, NewOrder); NewOrder = randomized; } - +bool Randstruct::isTriviallyRandomizable(const RecordDecl *D) const { + for (auto f : D->fields()){ + if(f->getFunctionType() == nullptr){ return false; } + } + return true; +} } // namespace clang diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 8f8b3671214b3..749659dbc065d 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2986,11 +2986,10 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { if (Entry) return *Entry; const ASTRecordLayout *NewEntry = nullptr; - - bool ShouldBeRandomized = D->getAttr() != nullptr; - if (true) { - Randstruct randstruct; - randstruct.reorganizeFields(*this, D); + Randstruct randstruct; + bool ShouldBeRandomized = randstruct.isTriviallyRandomizable(D) || D->getAttr() != nullptr; + if(ShouldBeRandomized){ + randstruct.reorganizeFields(*this, D); } if (isMsLayout(*this)) { From 63cf353e1361f3cc5b46eb99125509311ef06879 Mon Sep 17 00:00:00 2001 From: James Foster Date: Tue, 26 Feb 2019 04:38:33 +0000 Subject: [PATCH 3/8] Added comments --- clang/include/clang/AST/RecordFieldReorganizer.h | 1 + clang/lib/AST/RecordFieldReorganizer.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/clang/include/clang/AST/RecordFieldReorganizer.h b/clang/include/clang/AST/RecordFieldReorganizer.h index 494cfa9433c02..48d0b24a8989a 100644 --- a/clang/include/clang/AST/RecordFieldReorganizer.h +++ b/clang/include/clang/AST/RecordFieldReorganizer.h @@ -39,6 +39,7 @@ class RecordFieldReorganizer { class Randstruct : public RecordFieldReorganizer { public: + //Automatic Structure selection bool isTriviallyRandomizable(const RecordDecl *D) const; protected: virtual void reorganize(const ASTContext &C, const RecordDecl *D, diff --git a/clang/lib/AST/RecordFieldReorganizer.cpp b/clang/lib/AST/RecordFieldReorganizer.cpp index f02f0fe849c6c..88f8c2478e956 100644 --- a/clang/lib/AST/RecordFieldReorganizer.cpp +++ b/clang/lib/AST/RecordFieldReorganizer.cpp @@ -248,7 +248,10 @@ void Randstruct::reorganize(const ASTContext &C, const RecordDecl *D, NewOrder = randomized; } bool Randstruct::isTriviallyRandomizable(const RecordDecl *D) const { + for (auto f : D->fields()){ + //If an element of the structure does not have a + //function type is not a function pointer if(f->getFunctionType() == nullptr){ return false; } } return true; From b4446bd7effed1f960a48f69ed6e2374eb0fd159 Mon Sep 17 00:00:00 2001 From: James Foster Date: Wed, 27 Feb 2019 22:09:24 +0000 Subject: [PATCH 4/8] Removed unnecessary functions --- clang/include/clang/AST/RecordFieldReorganizer.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/AST/RecordFieldReorganizer.h b/clang/include/clang/AST/RecordFieldReorganizer.h index 48d0b24a8989a..eb027a3504128 100644 --- a/clang/include/clang/AST/RecordFieldReorganizer.h +++ b/clang/include/clang/AST/RecordFieldReorganizer.h @@ -34,12 +34,11 @@ class RecordFieldReorganizer { private: void commit(const RecordDecl *D, SmallVectorImpl &NewFieldOrder) const; - bool autostructselect(const SmallVector fields) const; }; class Randstruct : public RecordFieldReorganizer { -public: - //Automatic Structure selection +public: +/// Determines if the Record can be safely and easily randomized based on certain criteria (see implementation). bool isTriviallyRandomizable(const RecordDecl *D) const; protected: virtual void reorganize(const ASTContext &C, const RecordDecl *D, From 0a9f6954207cdbf8d5698c490ad7d892272214d0 Mon Sep 17 00:00:00 2001 From: Jordan Cantrell Date: Wed, 27 Feb 2019 14:15:42 -0800 Subject: [PATCH 5/8] adding flag --- clang/include/clang/Driver/Options.td | 2 ++ clang/lib/Driver/ToolChains/Clang.cpp | 4 ++++ clang/lib/Frontend/CompilerInvocation.cpp | 3 +++ 3 files changed, 9 insertions(+) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index cb7efbf3edd47..b42a296175e0c 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1751,6 +1751,8 @@ def freroll_loops : Flag<["-"], "freroll-loops">, Group, HelpText<"Turn on loop reroller">, Flags<[CC1Option]>; def fno_reroll_loops : Flag<["-"], "fno-reroll-loops">, Group, HelpText<"Turn off loop reroller">; +def thisisaflagpleasechangeme : Flag<["-"], "thisisaflagpleasechangeme">, Group, + HelpText<"Turn off auto selection for struct randomization">, Flags<[CC1Option]>; def ftrigraphs : Flag<["-"], "ftrigraphs">, Group, HelpText<"Process trigraph sequences">, Flags<[CC1Option]>; def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 920399c44b137..f6ca3289d4438 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4411,6 +4411,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue(0)); } + if (Arg *A = Args.getLastArg(options::OPT_thisisaflagpleasechangeme)) { + CmdArgs.push_back( "-thisisaflagpleasechangeme" ); + } + // -fvisibility= and -fvisibility-ms-compat are of a piece. if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ, options::OPT_fvisibility_ms_compat)) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 249b5d4c690db..7a672205304a2 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1674,6 +1674,9 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, if (const Arg* A = Args.getLastArg(OPT_frandstruct_seed)) { RandstructSeed = A->getValue(0); } + if (const Arg* A = Args.getLastArg(OPT_thisisaflagpleasechangeme)) { + RandstructFlag = true; + } Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin); for (const auto *AA : Args.filtered(OPT_plugin_arg)) Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1)); From 97166c8e8d21a713f0766b1f1b66f00e3e2c7dc5 Mon Sep 17 00:00:00 2001 From: James Foster Date: Wed, 27 Feb 2019 23:18:07 +0000 Subject: [PATCH 6/8] Refactored code for better readability --- clang/include/clang/AST/RecordFieldReorganizer.h | 2 +- clang/lib/AST/RecordFieldReorganizer.cpp | 6 ++++-- clang/lib/AST/RecordLayoutBuilder.cpp | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/AST/RecordFieldReorganizer.h b/clang/include/clang/AST/RecordFieldReorganizer.h index eb027a3504128..9f65d85a63dbe 100644 --- a/clang/include/clang/AST/RecordFieldReorganizer.h +++ b/clang/include/clang/AST/RecordFieldReorganizer.h @@ -39,7 +39,7 @@ class RecordFieldReorganizer { class Randstruct : public RecordFieldReorganizer { public: /// Determines if the Record can be safely and easily randomized based on certain criteria (see implementation). - bool isTriviallyRandomizable(const RecordDecl *D) const; + static bool isTriviallyRandomizable(const RecordDecl *D); protected: virtual void reorganize(const ASTContext &C, const RecordDecl *D, SmallVector &NewOrder) const override; diff --git a/clang/lib/AST/RecordFieldReorganizer.cpp b/clang/lib/AST/RecordFieldReorganizer.cpp index 88f8c2478e956..99aa55b89bd24 100644 --- a/clang/lib/AST/RecordFieldReorganizer.cpp +++ b/clang/lib/AST/RecordFieldReorganizer.cpp @@ -247,8 +247,10 @@ void Randstruct::reorganize(const ASTContext &C, const RecordDecl *D, SmallVector randomized = perfrandomize(C, NewOrder); NewOrder = randomized; } -bool Randstruct::isTriviallyRandomizable(const RecordDecl *D) const { - +bool Randstruct::isTriviallyRandomizable(const RecordDecl *D) { + /*if(D->getAttr() != nullptr){ + return false; + }*/ for (auto f : D->fields()){ //If an element of the structure does not have a //function type is not a function pointer diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 749659dbc065d..e58a5f23eae16 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2986,9 +2986,9 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const { if (Entry) return *Entry; const ASTRecordLayout *NewEntry = nullptr; - Randstruct randstruct; - bool ShouldBeRandomized = randstruct.isTriviallyRandomizable(D) || D->getAttr() != nullptr; + bool ShouldBeRandomized = Randstruct::isTriviallyRandomizable(D) || D->getAttr() != nullptr; if(ShouldBeRandomized){ + Randstruct randstruct; randstruct.reorganizeFields(*this, D); } From 2a220f219a7afb8497b39ffa546bfc600275d1e9 Mon Sep 17 00:00:00 2001 From: Connor Kuehl Date: Wed, 27 Feb 2019 23:41:23 +0000 Subject: [PATCH 7/8] Delete NoRandomizeLayout check This will be checked at our entry point, so we don't need to check this here. --- clang/lib/AST/RecordFieldReorganizer.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/clang/lib/AST/RecordFieldReorganizer.cpp b/clang/lib/AST/RecordFieldReorganizer.cpp index 25d1a1bbad3dd..6bbe272184cd9 100644 --- a/clang/lib/AST/RecordFieldReorganizer.cpp +++ b/clang/lib/AST/RecordFieldReorganizer.cpp @@ -254,9 +254,6 @@ void Randstruct::reorganize(const ASTContext &C, const RecordDecl *D, NewOrder = randomized; } bool Randstruct::isTriviallyRandomizable(const RecordDecl *D) { - /*if(D->getAttr() != nullptr){ - return false; - }*/ for (auto f : D->fields()){ //If an element of the structure does not have a //function type is not a function pointer From 2c5f3ebb276a78d7d08e8c40be4a483f09c7e09f Mon Sep 17 00:00:00 2001 From: James Foster Date: Thu, 28 Feb 2019 00:24:08 +0000 Subject: [PATCH 8/8] Added changes requested by Nixoncole --- clang/include/clang/Driver/Options.td | 2 +- clang/lib/AST/RecordFieldReorganizer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d4736df95f7fb..edf714adbf936 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1753,7 +1753,7 @@ def fno_reroll_loops : Flag<["-"], "fno-reroll-loops">, Group, HelpText<"Turn off loop reroller">; def randstruct_auto : Flag<["-"], "randstruct-auto">, HelpText<"Enable automatic structure selection for field randomization; " - "disabled with no_randomize_layout">, Flags<[CC1Option]>; + "Disable for specific structures with attribute no_randomize_layout">, Flags<[CC1Option]>; def ftrigraphs : Flag<["-"], "ftrigraphs">, Group, HelpText<"Process trigraph sequences">, Flags<[CC1Option]>; def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group, diff --git a/clang/lib/AST/RecordFieldReorganizer.cpp b/clang/lib/AST/RecordFieldReorganizer.cpp index 6bbe272184cd9..91783fd7cd415 100644 --- a/clang/lib/AST/RecordFieldReorganizer.cpp +++ b/clang/lib/AST/RecordFieldReorganizer.cpp @@ -257,7 +257,7 @@ bool Randstruct::isTriviallyRandomizable(const RecordDecl *D) { for (auto f : D->fields()){ //If an element of the structure does not have a //function type is not a function pointer - if(f->getFunctionType() == nullptr){ return false; } + if(f->getFunctionType() == nullptr){ return false; } } return true; }