Skip to content

Commit 54226c7

Browse files
connorkuehlNixoncolejeffreytakahashi
committed
Revert deletion of no_randomize_Layout code
This reverts commits * f06d4cc. * 9949798. Co-Authored-By: Cole Nixon <[email protected]> Co-Authored-By: Jeff Takahashi <[email protected]>
1 parent 3a0479d commit 54226c7

8 files changed

+61
-14
lines changed

clang/include/clang/AST/RecordFieldReorganizer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class RecordFieldReorganizer {
3737
};
3838

3939
class Randstruct : public RecordFieldReorganizer {
40-
public:
40+
public:
4141
/// Determines if the Record can be safely and easily randomized based on certain criteria (see implementation).
4242
static bool isTriviallyRandomizable(const RecordDecl *D);
4343
protected:

clang/include/clang/Basic/Attr.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3208,3 +3208,10 @@ def RandomizeLayout : InheritableAttr {
32083208
let Subjects = SubjectList<[Record]>;
32093209
let Documentation = [ClangRandstructDocs];
32103210
}
3211+
3212+
def NoRandomizeLayout : InheritableAttr {
3213+
let Spellings = [GCC<"no_randomize_layout">, Declspec<"no_randomize_layout">,
3214+
Keyword<"no_randomize_layout">];
3215+
let Subjects = SubjectList<[Record]>;
3216+
let Documentation = [ClangRandstructDocs];
3217+
}

clang/include/clang/Basic/AttrDocs.td

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4099,10 +4099,24 @@ When compiled without ``-fobjc-arc``, this attribute is ignored.
40994099

41004100
def ClangRandstructDocs : Documentation {
41014101
let Category = DocCatVariable;
4102+
let Heading = "randomize_layout, no_randomize_layout";
41024103
let Content = [{
4103-
The attribute ``randomize_layout`` can be applied to the declaration of
4104-
a record. ``randomize_layout`` instructs the compiler to randomize the memory layout
4104+
The attributes ``randomize_layout`` and ``no_randomize_layout`` can be applied
4105+
to a record.
4106+
4107+
``randomize_layout`` instructs the compiler to randomize the memory layout
41054108
of the member variables of the record.
4109+
4110+
Conversely, ``no_randomize_layout`` is used to indicate that if using the
4111+
automatic strucuture selection feature of the Randstruct implementation, the
4112+
compiler should not shuffle the members of the record.
4113+
4114+
In the event that a record is labeled with both attributes, the compiler will
4115+
emit a warning indicating that these two cannot be used on the same record.
4116+
The default behavior in this case is to not randomize the struct, as the
4117+
attribute ``no_randomize_layout`` takes precedence over ``randomize_layout``.
4118+
This is implementation defined behavior.
4119+
41064120
.. code-block:: c
41074121

41084122
// Indicates that this struct should be randomized by Randstruct implementation.
@@ -4111,5 +4125,19 @@ of the member variables of the record.
41114125
char *b;
41124126
char *c;
41134127
}__attribute__((randomize_layout));
4128+
4129+
// Indicates that this struct should NOT be randomized by Randstruct implementation.
4130+
struct s {
4131+
char *a;
4132+
char *b;
4133+
char *c;
4134+
}__attribute__((no_randomize_layout));
4135+
4136+
// Emits compiler warning. Struct is NOT randomized by Randstruct implementation.
4137+
struct s {
4138+
char *a;
4139+
char *b;
4140+
char *c;
4141+
}__attribute__((randomize_layout)) __attribute__((no_randomize_layout));
41144142
}];
41154143
}

clang/include/clang/Basic/DiagnosticASTKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,4 +345,7 @@ def warn_unnecessary_packed : Warning<
345345
"packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore;
346346
def warn_randomize_attr_union : Warning<
347347
"union declared with 'randomize_layout' attribute">, InGroup<DiagGroup<"randomize-layout">>;
348+
def warn_randomize_attr_conflict : Warning<
349+
"struct declared with 'randomize_layout' and 'no_randomize_layout' attributes; "
350+
"attribute 'no_randomize_layout' takes precedence">, InGroup<DiagGroup<"no-randomize-layout">>;
348351
}

clang/lib/AST/RecordFieldReorganizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ void Randstruct::reorganize(const ASTContext &C, const RecordDecl *D,
255255
}
256256
bool Randstruct::isTriviallyRandomizable(const RecordDecl *D) {
257257
for (auto f : D->fields()){
258-
//If an element of the structure does not have a
258+
//If an element of the structure does not have a
259259
//function type is not a function pointer
260260
if(f->getFunctionType() == nullptr){ return false; }
261261
}

clang/lib/AST/RecordLayoutBuilder.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,17 +2988,22 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
29882988

29892989
const ASTRecordLayout *NewEntry = nullptr;
29902990

2991-
bool ShouldBeRandomized = (RandstructAutoSelect && Randstruct::isTriviallyRandomizable(D)) || D->getAttr<RandomizeLayoutAttr>() != nullptr;
2992-
if (ShouldBeRandomized) {
2993-
// There is no technical benefit to randomizing the fields of a union
2994-
// since they all share the same offset of zero.
2995-
if (D->isUnion()) {
2991+
bool ShouldBeRandomized = D->getAttr<RandomizeLayoutAttr>() != nullptr;
2992+
bool NotToBeRandomized = D->getAttr<NoRandomizeLayoutAttr>() != nullptr;
2993+
bool AutoSelectable = RandstructAutoSelect && Randstruct::isTriviallyRandomizable(D);
2994+
2995+
if (ShouldBeRandomized && NotToBeRandomized) {
2996+
getDiagnostics().Report(D->getLocation(), diag::warn_randomize_attr_conflict);
2997+
}
2998+
2999+
if (ShouldBeRandomized && D->isUnion()) {
29963000
getDiagnostics().Report(D->getLocation(), diag::warn_randomize_attr_union);
2997-
}
2998-
else {
2999-
Randstruct randstruct;
3000-
randstruct.reorganizeFields(*this,D);
3001-
}
3001+
NotToBeRandomized = true;
3002+
}
3003+
3004+
if (!NotToBeRandomized && (ShouldBeRandomized || AutoSelectable)) {
3005+
Randstruct randstruct;
3006+
randstruct.reorganizeFields(*this,D);
30023007
}
30033008

30043009
if (isMsLayout(*this)) {

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6856,6 +6856,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
68566856
case ParsedAttr::AT_RandomizeLayout:
68576857
handleSimpleAttribute<RandomizeLayoutAttr>(S, D, AL);
68586858
break;
6859+
case ParsedAttr::AT_NoRandomizeLayout:
6860+
handleSimpleAttribute<NoRandomizeLayoutAttr>(S, D, AL);
6861+
break;
68596862
case ParsedAttr::AT_CodeSeg:
68606863
handleCodeSegAttr(S, D, AL);
68616864
break;

clang/test/Misc/pragma-attribute-supported-attributes-list.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
// CHECK-NEXT: NoInstrumentFunction (SubjectMatchRule_function)
8181
// CHECK-NEXT: NoMicroMips (SubjectMatchRule_function)
8282
// CHECK-NEXT: NoMips16 (SubjectMatchRule_function)
83+
// CHECK-NEXT: NoRandomizeLayout (SubjectMatchRule_record)
8384
// CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
8485
// CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
8586
// CHECK-NEXT: NoSpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method)

0 commit comments

Comments
 (0)