{ CACHE_LINE = 64 };
43 virtual~Bucket() =
default;
46 voidaddField(
FieldDecl*Field,
intFieldSize);
47 virtual boolcanFit(
intFieldSize)
const{
48 return Size+ FieldSize <= CACHE_LINE;
50 virtual boolisBitfieldRun()
const{
return false; }
51 boolfull()
const{
return Size>= CACHE_LINE; }
54voidBucket::addField(
FieldDecl*Field,
intFieldSize) {
56Fields.push_back(Field);
59structBitfieldRunBucket :
publicBucket {
60 boolcanFit(
intFieldSize)
const override{
return true; }
61 boolisBitfieldRun()
const override{
return true; }
64voidrandomizeStructureLayoutImpl(
const ASTContext&Context,
71std::unique_ptr<Bucket> CurrentBucket;
75std::unique_ptr<BitfieldRunBucket> CurrentBitfieldRun;
81 while(!FieldsOut.empty()) {
85 if(Skipped >= FieldsOut.size()) {
87Buckets.push_back(std::move(CurrentBucket));
91 autoFieldIter = FieldsOut.begin();
96 if(!CurrentBitfieldRun)
97CurrentBitfieldRun = std::make_unique<BitfieldRunBucket>();
101CurrentBitfieldRun->addField(FD,
1);
102FieldsOut.erase(FieldIter);
108 if(CurrentBitfieldRun)
109Buckets.push_back(std::move(CurrentBitfieldRun));
113CurrentBucket = std::make_unique<Bucket>();
116 if(Width >= CACHE_LINE) {
117std::unique_ptr<Bucket> OverSized = std::make_unique<Bucket>();
118OverSized->addField(FD, Width);
119FieldsOut.erase(FieldIter);
120Buckets.push_back(std::move(OverSized));
125 if(CurrentBucket->canFit(Width)) {
126CurrentBucket->addField(FD, Width);
127FieldsOut.erase(FieldIter);
130 if(CurrentBucket->full()) {
132Buckets.push_back(std::move(CurrentBucket));
138FieldsOut.push_back(FD);
139FieldsOut.erase(FieldIter);
147Buckets.push_back(std::move(CurrentBucket));
150 if(CurrentBitfieldRun)
151Buckets.push_back(std::move(CurrentBitfieldRun));
153std::shuffle(std::begin(Buckets), std::end(Buckets), RNG);
157 for(
conststd::unique_ptr<Bucket> &B : Buckets) {
159 if(!B->isBitfieldRun())
160std::shuffle(std::begin(RandFields), std::end(RandFields), RNG);
162FinalOrder.insert(FinalOrder.end(), RandFields.begin(), RandFields.end());
165FieldsOut = FinalOrder;
171namespacerandstruct {
178 unsignedTotalNumFields = 0;
181 if(
auto*FD = dyn_cast<FieldDecl>(
D))
182RandomizedFields.push_back(FD);
183 else if(isa<StaticAssertDecl>(
D) || isa<IndirectFieldDecl>(
D))
184PostRandomizedFields.push_back(
D);
186FinalOrdering.push_back(
D);
189 if(RandomizedFields.empty())
196 if(!FlexibleArray) {
197 if(
const auto*CA =
198dyn_cast<ConstantArrayType>(RandomizedFields.back()->getType()))
199 if(CA->getSize().sle(2))
200FlexibleArray = RandomizedFields.pop_back_val();
205std::seed_seq SeedSeq(Seed.begin(), Seed.end());
206std::mt19937 RNG(SeedSeq);
208randomizeStructureLayoutImpl(Context, RandomizedFields, RNG);
211FinalOrdering.insert(FinalOrdering.end(), RandomizedFields.begin(),
212RandomizedFields.end());
215FinalOrdering.insert(FinalOrdering.end(), PostRandomizedFields.begin(),
216PostRandomizedFields.end());
220FinalOrdering.push_back(FlexibleArray);
222assert(TotalNumFields == FinalOrdering.size() &&
223 "Decl count has been altered after Randstruct randomization!");
224(void)TotalNumFields;
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const LangOptions & getLangOpts() const
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
bool isZeroLengthBitField() const
Is this a zero-length bit-field? Such bit-fields aren't really bit-fields at all and instead act as a...
std::string RandstructSeed
The seed used by the randomize structure layout feature.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
bool randomizeStructureLayout(const ASTContext &Context, RecordDecl *RD, llvm::SmallVectorImpl< Decl * > &FinalOrdering)
The JSON file list parser is used to communicate input to InstallAPI.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4