@@ -218,7 +218,7 @@ class HWAddressSanitizer {
218
218
Value *getUARTag (IRBuilder<> &IRB, Value *StackTag);
219
219
220
220
Value *getHwasanThreadSlotPtr (IRBuilder<> &IRB, Type *Ty);
221
- Value * emitPrologue (IRBuilder<> &IRB, bool WithFrameRecord);
221
+ void emitPrologue (IRBuilder<> &IRB, bool WithFrameRecord);
222
222
223
223
private:
224
224
LLVMContext *C;
@@ -284,6 +284,7 @@ class HWAddressSanitizer {
284
284
Constant *ShadowGlobal;
285
285
286
286
Value *LocalDynamicShadow = nullptr ;
287
+ Value *StackBaseTag = nullptr ;
287
288
GlobalValue *ThreadPtrGlobal = nullptr ;
288
289
};
289
290
@@ -750,10 +751,16 @@ static unsigned RetagMask(unsigned AllocaNo) {
750
751
// x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these
751
752
// masks.
752
753
// The list does not include the value 255, which is used for UAR.
753
- static unsigned FastMasks[] = {
754
- 0 , 1 , 2 , 3 , 4 , 6 , 7 , 8 , 12 , 14 , 15 , 16 , 24 ,
755
- 28 , 30 , 31 , 32 , 48 , 56 , 60 , 62 , 63 , 64 , 96 , 112 , 120 ,
756
- 124 , 126 , 127 , 128 , 192 , 224 , 240 , 248 , 252 , 254 };
754
+ //
755
+ // Because we are more likely to use earlier elements of this list than later
756
+ // ones, it is sorted in increasing order of probability of collision with a
757
+ // mask allocated (temporally) nearby. The program that generated this list
758
+ // can be found at:
759
+ // https://github.com/google/sanitizers/blob/master/hwaddress-sanitizer/sort_masks.py
760
+ static unsigned FastMasks[] = {0 , 128 , 64 , 192 , 32 , 96 , 224 , 112 , 240 ,
761
+ 48 , 16 , 120 , 248 , 56 , 24 , 8 , 124 , 252 ,
762
+ 60 , 28 , 12 , 4 , 126 , 254 , 62 , 30 , 14 ,
763
+ 6 , 2 , 127 , 63 , 31 , 15 , 7 , 3 , 1 };
757
764
return FastMasks[AllocaNo % (sizeof (FastMasks) / sizeof (FastMasks[0 ]))];
758
765
}
759
766
@@ -764,6 +771,8 @@ Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
764
771
Value *HWAddressSanitizer::getStackBaseTag (IRBuilder<> &IRB) {
765
772
if (ClGenerateTagsWithCalls)
766
773
return getNextTagWithCall (IRB);
774
+ if (StackBaseTag)
775
+ return StackBaseTag;
767
776
// FIXME: use addressofreturnaddress (but implement it in aarch64 backend
768
777
// first).
769
778
Module *M = IRB.GetInsertBlock ()->getParent ()->getParent ();
@@ -881,13 +890,16 @@ void HWAddressSanitizer::createFrameGlobal(Function &F,
881
890
GV->setComdat (Comdat);
882
891
}
883
892
884
- Value *HWAddressSanitizer::emitPrologue (IRBuilder<> &IRB,
885
- bool WithFrameRecord) {
886
- if (!Mapping.InTls )
887
- return getDynamicShadowNonTls (IRB);
893
+ void HWAddressSanitizer::emitPrologue (IRBuilder<> &IRB, bool WithFrameRecord) {
894
+ if (!Mapping.InTls ) {
895
+ LocalDynamicShadow = getDynamicShadowNonTls (IRB);
896
+ return ;
897
+ }
888
898
889
- if (!WithFrameRecord && TargetTriple.isAndroid ())
890
- return getDynamicShadowIfunc (IRB);
899
+ if (!WithFrameRecord && TargetTriple.isAndroid ()) {
900
+ LocalDynamicShadow = getDynamicShadowIfunc (IRB);
901
+ return ;
902
+ }
891
903
892
904
Value *SlotPtr = getHwasanThreadSlotPtr (IRB, IntptrTy);
893
905
assert (SlotPtr);
@@ -920,6 +932,8 @@ Value *HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB,
920
932
TargetTriple.isAArch64 () ? ThreadLong : untagPointer (IRB, ThreadLong);
921
933
922
934
if (WithFrameRecord) {
935
+ StackBaseTag = IRB.CreateAShr (ThreadLong, 3 );
936
+
923
937
// Prepare ring buffer data.
924
938
auto PC = IRB.CreatePtrToInt (F, IntptrTy);
925
939
auto GetStackPointerFn =
@@ -928,7 +942,7 @@ Value *HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB,
928
942
IRB.CreateCall (GetStackPointerFn,
929
943
{Constant::getNullValue (IRB.getInt32Ty ())}),
930
944
IntptrTy);
931
- // Mix SP and PC. TODO: also add the tag to the mix.
945
+ // Mix SP and PC.
932
946
// Assumptions:
933
947
// PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero)
934
948
// SP is 0xsssssssssssSSSS0 (4 lower bits are zero)
@@ -959,13 +973,12 @@ Value *HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB,
959
973
// Get shadow base address by aligning RecordPtr up.
960
974
// Note: this is not correct if the pointer is already aligned.
961
975
// Runtime library will make sure this never happens.
962
- Value *ShadowBase = IRB.CreateAdd (
976
+ LocalDynamicShadow = IRB.CreateAdd (
963
977
IRB.CreateOr (
964
978
ThreadLongMaybeUntagged,
965
979
ConstantInt::get (IntptrTy, (1ULL << kShadowBaseAlignment ) - 1 )),
966
980
ConstantInt::get (IntptrTy, 1 ), " hwasan.shadow" );
967
- ShadowBase = IRB.CreateIntToPtr (ShadowBase, Int8PtrTy);
968
- return ShadowBase;
981
+ LocalDynamicShadow = IRB.CreateIntToPtr (LocalDynamicShadow, Int8PtrTy);
969
982
}
970
983
971
984
bool HWAddressSanitizer::instrumentLandingPads (
@@ -1115,9 +1128,9 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
1115
1128
1116
1129
Instruction *InsertPt = &*F.getEntryBlock ().begin ();
1117
1130
IRBuilder<> EntryIRB (InsertPt);
1118
- LocalDynamicShadow = emitPrologue (EntryIRB,
1119
- /* WithFrameRecord*/ ClRecordStackHistory &&
1120
- !AllocasToInstrument.empty ());
1131
+ emitPrologue (EntryIRB,
1132
+ /* WithFrameRecord*/ ClRecordStackHistory &&
1133
+ !AllocasToInstrument.empty ());
1121
1134
1122
1135
bool Changed = false ;
1123
1136
if (!AllocasToInstrument.empty ()) {
@@ -1146,6 +1159,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
1146
1159
Changed |= instrumentMemAccess (Inst);
1147
1160
1148
1161
LocalDynamicShadow = nullptr ;
1162
+ StackBaseTag = nullptr ;
1149
1163
1150
1164
return Changed;
1151
1165
}
0 commit comments