Skip to content

Commit 5f36042

Browse files
authored
[NFC] [HWASan] [MTE] factor out threadlong increment (#110340)
1 parent 87b491a commit 5f36042

File tree

4 files changed

+39
-42
lines changed

4 files changed

+39
-42
lines changed

llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ Value *getPC(const Triple &TargetTriple, IRBuilder<> &IRB);
9999
Value *getAndroidSlotPtr(IRBuilder<> &IRB, int Slot);
100100

101101
void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag);
102+
Value *incrementThreadLong(IRBuilder<> &IRB, Value *ThreadLong,
103+
unsigned int Inc);
102104

103105
} // namespace memtag
104106
} // namespace llvm

llvm/lib/Target/AArch64/AArch64StackTagging.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -506,19 +506,8 @@ Instruction *AArch64StackTagging::insertBaseTaggedPointer(
506506
Value *RecordPtr = IRB.CreateIntToPtr(ThreadLong, IRB.getPtrTy(0));
507507
IRB.CreateStore(PC, RecordPtr);
508508
IRB.CreateStore(TaggedFP, IRB.CreateConstGEP1_64(IntptrTy, RecordPtr, 1));
509-
// Update the ring buffer. Top byte of ThreadLong defines the size of the
510-
// buffer in pages, it must be a power of two, and the start of the buffer
511-
// must be aligned by twice that much. Therefore wrap around of the ring
512-
// buffer is simply Addr &= ~((ThreadLong >> 56) << 12).
513-
// The use of AShr instead of LShr is due to
514-
// https://bugs.llvm.org/show_bug.cgi?id=39030
515-
// Runtime library makes sure not to use the highest bit.
516-
Value *WrapMask = IRB.CreateXor(
517-
IRB.CreateShl(IRB.CreateAShr(ThreadLong, 56), 12, "", true, true),
518-
ConstantInt::get(IntptrTy, (uint64_t)-1));
519-
Value *ThreadLongNew = IRB.CreateAnd(
520-
IRB.CreateAdd(ThreadLong, ConstantInt::get(IntptrTy, 16)), WrapMask);
521-
IRB.CreateStore(ThreadLongNew, SlotPtr);
509+
510+
IRB.CreateStore(memtag::incrementThreadLong(IRB, ThreadLong, 16), SlotPtr);
522511
}
523512
return Base;
524513
}

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,35 +1421,7 @@ void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
14211421
IRB.CreateIntToPtr(ThreadLongMaybeUntagged, IRB.getPtrTy(0));
14221422
IRB.CreateStore(FrameRecordInfo, RecordPtr);
14231423

1424-
// Update the ring buffer. Top byte of ThreadLong defines the size of the
1425-
// buffer in pages, it must be a power of two, and the start of the buffer
1426-
// must be aligned by twice that much. Therefore wrap around of the ring
1427-
// buffer is simply Addr &= ~((ThreadLong >> 56) << 12).
1428-
// The use of AShr instead of LShr is due to
1429-
// https://bugs.llvm.org/show_bug.cgi?id=39030
1430-
// Runtime library makes sure not to use the highest bit.
1431-
//
1432-
// Mechanical proof of this address calculation can be found at:
1433-
// https://github.com/google/sanitizers/blob/master/hwaddress-sanitizer/prove_hwasanwrap.smt2
1434-
//
1435-
// Example of the wrap case for N = 1
1436-
// Pointer: 0x01AAAAAAAAAAAFF8
1437-
// +
1438-
// 0x0000000000000008
1439-
// =
1440-
// 0x01AAAAAAAAAAB000
1441-
// &
1442-
// WrapMask: 0xFFFFFFFFFFFFF000
1443-
// =
1444-
// 0x01AAAAAAAAAAA000
1445-
//
1446-
// Then the WrapMask will be a no-op until the next wrap case.
1447-
Value *WrapMask = IRB.CreateXor(
1448-
IRB.CreateShl(IRB.CreateAShr(ThreadLong, 56), 12, "", true, true),
1449-
ConstantInt::get(IntptrTy, (uint64_t)-1));
1450-
Value *ThreadLongNew = IRB.CreateAnd(
1451-
IRB.CreateAdd(ThreadLong, ConstantInt::get(IntptrTy, 8)), WrapMask);
1452-
IRB.CreateStore(ThreadLongNew, SlotPtr);
1424+
IRB.CreateStore(memtag::incrementThreadLong(IRB, ThreadLong, 8), SlotPtr);
14531425
break;
14541426
}
14551427
case none: {

llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,5 +338,39 @@ void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag) {
338338
llvm::for_each(Info.DbgVariableRecords, AnnotateDbgRecord);
339339
}
340340

341+
Value *incrementThreadLong(IRBuilder<> &IRB, Value *ThreadLong,
342+
unsigned int Inc) {
343+
// Update the ring buffer. Top byte of ThreadLong defines the size of the
344+
// buffer in pages, it must be a power of two, and the start of the buffer
345+
// must be aligned by twice that much. Therefore wrap around of the ring
346+
// buffer is simply Addr &= ~((ThreadLong >> 56) << 12).
347+
// The use of AShr instead of LShr is due to
348+
// https://bugs.llvm.org/show_bug.cgi?id=39030
349+
// Runtime library makes sure not to use the highest bit.
350+
//
351+
// Mechanical proof of this address calculation can be found at:
352+
// https://github.com/google/sanitizers/blob/master/hwaddress-sanitizer/prove_hwasanwrap.smt2
353+
//
354+
// Example of the wrap case for N = 1
355+
// Pointer: 0x01AAAAAAAAAAAFF8
356+
// +
357+
// 0x0000000000000008
358+
// =
359+
// 0x01AAAAAAAAAAB000
360+
// &
361+
// WrapMask: 0xFFFFFFFFFFFFF000
362+
// =
363+
// 0x01AAAAAAAAAAA000
364+
//
365+
// Then the WrapMask will be a no-op until the next wrap case.
366+
assert((4096 % Inc) == 0);
367+
Value *WrapMask = IRB.CreateXor(
368+
IRB.CreateShl(IRB.CreateAShr(ThreadLong, 56), 12, "", true, true),
369+
ConstantInt::get(ThreadLong->getType(), (uint64_t)-1));
370+
return IRB.CreateAnd(
371+
IRB.CreateAdd(ThreadLong, ConstantInt::get(ThreadLong->getType(), Inc)),
372+
WrapMask);
373+
}
374+
341375
} // namespace memtag
342376
} // namespace llvm

0 commit comments

Comments
 (0)