Skip to content

Commit 9df0754

Browse files
committed
AddressSanitizer: 64-bit SPARC/Linux port
Summary: This patch contains the bits required to make the AddressSanitizer work on SPARC64/Linux (SPARC-T4 and later). Patch by Eric Botcazou. Reviewers: #sanitizers, vitalybuka, krytarowski Reviewed By: #sanitizers, vitalybuka Subscribers: brad, vitalybuka, ro, jyknight, kubamracek, fedor.sergeev, jdoerfert, llvm-commits, #sanitizers Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D58434 llvm-svn: 355980
1 parent 5ae9f86 commit 9df0754

File tree

3 files changed

+118
-1
lines changed

3 files changed

+118
-1
lines changed

compiler-rt/lib/asan/asan_allocator.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,15 @@ const uptr kAllocatorSpace = ~(uptr)0;
133133
const uptr kAllocatorSize = 0x2000000000ULL; // 128G.
134134
typedef VeryCompactSizeClassMap SizeClassMap;
135135
# elif defined(__aarch64__)
136-
// AArch64/SANITIZER_CAN_USER_ALLOCATOR64 is only for 42-bit VMA
136+
// AArch64/SANITIZER_CAN_USE_ALLOCATOR64 is only for 42-bit VMA
137137
// so no need to different values for different VMA.
138138
const uptr kAllocatorSpace = 0x10000000000ULL;
139139
const uptr kAllocatorSize = 0x10000000000ULL; // 3T.
140140
typedef DefaultSizeClassMap SizeClassMap;
141+
#elif defined(__sparc__)
142+
const uptr kAllocatorSpace = ~(uptr)0;
143+
const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
144+
typedef DefaultSizeClassMap SizeClassMap;
141145
# elif SANITIZER_WINDOWS
142146
const uptr kAllocatorSpace = ~(uptr)0;
143147
const uptr kAllocatorSize = 0x8000000000ULL; // 500G

compiler-rt/lib/asan/asan_mapping.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@
100100
// || `[0x10000000000000, 0x11ffffffffffff]` || LowShadow ||
101101
// || `[0x00000000000000, 0x0fffffffffffff]` || LowMem ||
102102
//
103+
// Default Linux/SPARC64 (52-bit VMA) mapping:
104+
// || `[0x8000000000000, 0xfffffffffffff]` || HighMem ||
105+
// || `[0x1080000000000, 0x207ffffffffff]` || HighShadow ||
106+
// || `[0x0090000000000, 0x107ffffffffff]` || ShadowGap ||
107+
// || `[0x0080000000000, 0x008ffffffffff]` || LowShadow ||
108+
// || `[0x0000000000000, 0x007ffffffffff]` || LowMem ||
109+
//
103110
// Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
104111
// || `[0x500000000000, 0x7fffffffffff]` || HighMem ||
105112
// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
@@ -162,6 +169,7 @@ static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
162169
static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
163170
static const u64 kPPC64_ShadowOffset64 = 1ULL << 44;
164171
static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
172+
static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43; // 0x80000000000
165173
static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
166174
static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000
167175
static const u64 kNetBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
@@ -224,6 +232,8 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
224232
# define SHADOW_OFFSET kDefaultShadowOffset64
225233
# elif defined(__mips64)
226234
# define SHADOW_OFFSET kMIPS64_ShadowOffset64
235+
#elif defined(__sparc__)
236+
#define SHADOW_OFFSET kSPARC64_ShadowOffset64
227237
# elif SANITIZER_WINDOWS64
228238
# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
229239
# else
@@ -270,6 +280,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
270280

271281
#if SANITIZER_MYRIAD2
272282
#include "asan_mapping_myriad.h"
283+
#elif defined(__sparc__) && SANITIZER_WORDSIZE == 64
284+
#include "asan_mapping_sparc64.h"
273285
#else
274286
#define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET))
275287

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//===-- asan_mapping_sparc64.h ----------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a part of AddressSanitizer, an address sanity checker.
10+
//
11+
// SPARC64-specific definitions for ASan memory mapping.
12+
//===----------------------------------------------------------------------===//
13+
#ifndef ASAN_MAPPING_SPARC64_H
14+
#define ASAN_MAPPING_SPARC64_H
15+
16+
// This is tailored to the 52-bit VM layout on SPARC-T4 and later.
17+
// The VM space is split into two 51-bit halves at both ends: the low part
18+
// has all the bits above the 51st cleared, while the high part has them set.
19+
// 0xfff8000000000000 - 0xffffffffffffffff
20+
// 0x0000000000000000 - 0x0007ffffffffffff
21+
22+
#define VMA_BITS 52
23+
#define HIGH_BITS (64 - VMA_BITS)
24+
25+
// The idea is to chop the high bits before doing the scaling, so the two
26+
// parts become contiguous again and the usual scheme can be applied.
27+
28+
#define MEM_TO_SHADOW(mem) \
29+
((((mem) << HIGH_BITS) >> (HIGH_BITS + (SHADOW_SCALE))) + (SHADOW_OFFSET))
30+
31+
#define kLowMemBeg 0
32+
#define kLowMemEnd (SHADOW_OFFSET - 1)
33+
34+
#define kLowShadowBeg SHADOW_OFFSET
35+
#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
36+
37+
// But of course there is the huge hole between the high shadow memory,
38+
// which is in the low part, and the beginning of the high part.
39+
40+
#define kHighMemBeg (-(1ULL << (VMA_BITS - 1)))
41+
42+
#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
43+
#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
44+
45+
#define kMidShadowBeg 0
46+
#define kMidShadowEnd 0
47+
48+
// With the zero shadow base we can not actually map pages starting from 0.
49+
// This constant is somewhat arbitrary.
50+
#define kZeroBaseShadowStart 0
51+
#define kZeroBaseMaxShadowStart (1 << 18)
52+
53+
#define kShadowGapBeg (kLowShadowEnd + 1)
54+
#define kShadowGapEnd (kHighShadowBeg - 1)
55+
56+
#define kShadowGap2Beg 0
57+
#define kShadowGap2End 0
58+
59+
#define kShadowGap3Beg 0
60+
#define kShadowGap3End 0
61+
62+
namespace __asan {
63+
64+
static inline bool AddrIsInLowMem(uptr a) {
65+
PROFILE_ASAN_MAPPING();
66+
return a <= kLowMemEnd;
67+
}
68+
69+
static inline bool AddrIsInLowShadow(uptr a) {
70+
PROFILE_ASAN_MAPPING();
71+
return a >= kLowShadowBeg && a <= kLowShadowEnd;
72+
}
73+
74+
static inline bool AddrIsInMidMem(uptr a) {
75+
PROFILE_ASAN_MAPPING();
76+
return false;
77+
}
78+
79+
static inline bool AddrIsInMidShadow(uptr a) {
80+
PROFILE_ASAN_MAPPING();
81+
return false;
82+
}
83+
84+
static inline bool AddrIsInHighMem(uptr a) {
85+
PROFILE_ASAN_MAPPING();
86+
return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
87+
}
88+
89+
static inline bool AddrIsInHighShadow(uptr a) {
90+
PROFILE_ASAN_MAPPING();
91+
return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
92+
}
93+
94+
static inline bool AddrIsInShadowGap(uptr a) {
95+
PROFILE_ASAN_MAPPING();
96+
return a >= kShadowGapBeg && a <= kShadowGapEnd;
97+
}
98+
99+
} // namespace __asan
100+
101+
#endif // ASAN_MAPPING_SPARC64_H

0 commit comments

Comments
 (0)