Skip to content

Commit eeb6be1

Browse files
committed
Sign-extend addresses in CompactRingBuffer.
Summary: This is neccessary to support solaris/sparc9 where some userspace addresses have all top bits set, as well as, potentially, kernel memory on aarch64. This change does not update the compiler side (HWASan IR pass) which needs to be done separately for the affected targets. Reviewers: ro, vitalybuka Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D91827
1 parent dd75c0e commit eeb6be1

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_ring_buffer.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,23 +86,28 @@ class CompactRingBuffer {
8686
// Lower bytes store the address of the next buffer element.
8787
static constexpr int kPageSizeBits = 12;
8888
static constexpr int kSizeShift = 56;
89+
static constexpr int kSizeBits = 64 - kSizeShift;
8990
static constexpr uptr kNextMask = (1ULL << kSizeShift) - 1;
9091

9192
uptr GetStorageSize() const { return (long_ >> kSizeShift) << kPageSizeBits; }
9293

94+
static uptr SignExtend(uptr x) { return ((sptr)x) << kSizeBits >> kSizeBits; }
95+
9396
void Init(void *storage, uptr size) {
9497
CHECK_EQ(sizeof(CompactRingBuffer<T>), sizeof(void *));
9598
CHECK(IsPowerOfTwo(size));
9699
CHECK_GE(size, 1 << kPageSizeBits);
97100
CHECK_LE(size, 128 << kPageSizeBits);
98101
CHECK_EQ(size % 4096, 0);
99102
CHECK_EQ(size % sizeof(T), 0);
100-
CHECK_EQ((uptr)storage % (size * 2), 0);
101-
long_ = (uptr)storage | ((size >> kPageSizeBits) << kSizeShift);
103+
uptr st = (uptr)storage;
104+
CHECK_EQ(st % (size * 2), 0);
105+
CHECK_EQ(st, SignExtend(st & kNextMask));
106+
long_ = (st & kNextMask) | ((size >> kPageSizeBits) << kSizeShift);
102107
}
103108

104109
void SetNext(const T *next) {
105-
long_ = (long_ & ~kNextMask) | (uptr)next;
110+
long_ = (long_ & ~kNextMask) | ((uptr)next & kNextMask);
106111
}
107112

108113
public:
@@ -119,7 +124,7 @@ class CompactRingBuffer {
119124
SetNext((const T *)storage + Idx);
120125
}
121126

122-
T *Next() const { return (T *)(long_ & kNextMask); }
127+
T *Next() const { return (T *)(SignExtend(long_ & kNextMask)); }
123128

124129
void *StartOfStorage() const {
125130
return (void *)((uptr)Next() & ~(GetStorageSize() - 1));

0 commit comments

Comments
 (0)