mirror of
https://github.com/intel/llvm.git
synced 2026-02-01 00:46:45 +08:00
[compiler-rt] [tsan] Add support for PIE build on AArch64
This patch adds PIE executable support for aarch64-linux. It adds two more segments: - 0x05500000000-0x05600000000: 39-bits PIE program segments - 0x2aa00000000-0x2ab00000000: 42-bits PIE program segments Fortunately it is possible to use the same transformation formula for the new segments range with some adjustments in shadow to memory formula (it adds a constant offset based on the VMA size). A simple testcase is also added, however it is disabled on x86 due the fact it might fail on newer kernels [1]. [1] https://git.kernel.org/linus/d1fd836dcf00d2028c700c7e44d2c23404062c90 llvm-svn: 256184
This commit is contained in:
@@ -101,10 +101,12 @@ struct Mapping {
|
||||
C/C++ on linux/aarch64 (39-bit VMA)
|
||||
0000 0010 00 - 0100 0000 00: main binary
|
||||
0100 0000 00 - 0800 0000 00: -
|
||||
0800 0000 00 - 1F00 0000 00: shadow memory
|
||||
1C00 0000 00 - 3100 0000 00: -
|
||||
0800 0000 00 - 2000 0000 00: shadow memory
|
||||
2000 0000 00 - 3100 0000 00: -
|
||||
3100 0000 00 - 3400 0000 00: metainfo
|
||||
3400 0000 00 - 6000 0000 00: -
|
||||
3400 0000 00 - 5500 0000 00: -
|
||||
5500 0000 00 - 5600 0000 00: main binary (PIE)
|
||||
5600 0000 00 - 6000 0000 00: -
|
||||
6000 0000 00 - 6200 0000 00: traces
|
||||
6200 0000 00 - 7d00 0000 00: -
|
||||
7c00 0000 00 - 7d00 0000 00: heap
|
||||
@@ -114,14 +116,17 @@ struct Mapping39 {
|
||||
static const uptr kLoAppMemBeg = 0x0000001000ull;
|
||||
static const uptr kLoAppMemEnd = 0x0100000000ull;
|
||||
static const uptr kShadowBeg = 0x0800000000ull;
|
||||
static const uptr kShadowEnd = 0x1F00000000ull;
|
||||
static const uptr kShadowEnd = 0x2000000000ull;
|
||||
static const uptr kMetaShadowBeg = 0x3100000000ull;
|
||||
static const uptr kMetaShadowEnd = 0x3400000000ull;
|
||||
static const uptr kMidAppMemBeg = 0x5500000000ull;
|
||||
static const uptr kMidAppMemEnd = 0x5600000000ull;
|
||||
static const uptr kMidShadowOff = 0x5000000000ull;
|
||||
static const uptr kTraceMemBeg = 0x6000000000ull;
|
||||
static const uptr kTraceMemEnd = 0x6200000000ull;
|
||||
static const uptr kHeapMemBeg = 0x7c00000000ull;
|
||||
static const uptr kHeapMemEnd = 0x7d00000000ull;
|
||||
static const uptr kHiAppMemBeg = 0x7d00000000ull;
|
||||
static const uptr kHiAppMemBeg = 0x7e00000000ull;
|
||||
static const uptr kHiAppMemEnd = 0x7fffffffffull;
|
||||
static const uptr kAppMemMsk = 0x7800000000ull;
|
||||
static const uptr kAppMemXor = 0x0200000000ull;
|
||||
@@ -135,7 +140,9 @@ C/C++ on linux/aarch64 (42-bit VMA)
|
||||
10000 0000 00 - 20000 0000 00: shadow memory
|
||||
20000 0000 00 - 26000 0000 00: -
|
||||
26000 0000 00 - 28000 0000 00: metainfo
|
||||
28000 0000 00 - 36200 0000 00: -
|
||||
28000 0000 00 - 2aa00 0000 00: -
|
||||
2aa00 0000 00 - 2ab00 0000 00: main binary (PIE)
|
||||
2ab00 0000 00 - 36200 0000 00: -
|
||||
36200 0000 00 - 36240 0000 00: traces
|
||||
36240 0000 00 - 3e000 0000 00: -
|
||||
3e000 0000 00 - 3f000 0000 00: heap
|
||||
@@ -148,6 +155,9 @@ struct Mapping42 {
|
||||
static const uptr kShadowEnd = 0x20000000000ull;
|
||||
static const uptr kMetaShadowBeg = 0x26000000000ull;
|
||||
static const uptr kMetaShadowEnd = 0x28000000000ull;
|
||||
static const uptr kMidAppMemBeg = 0x2aa00000000ull;
|
||||
static const uptr kMidAppMemEnd = 0x2ab00000000ull;
|
||||
static const uptr kMidShadowOff = 0x28000000000ull;
|
||||
static const uptr kTraceMemBeg = 0x36200000000ull;
|
||||
static const uptr kTraceMemEnd = 0x36400000000ull;
|
||||
static const uptr kHeapMemBeg = 0x3e000000000ull;
|
||||
@@ -161,6 +171,8 @@ struct Mapping42 {
|
||||
|
||||
// Indicates the runtime will define the memory regions at runtime.
|
||||
#define TSAN_RUNTIME_VMA 1
|
||||
// Indicates that mapping defines a mid range memory segment.
|
||||
#define TSAN_MID_APP_RANGE 1
|
||||
#elif defined(__powerpc64__)
|
||||
// PPC64 supports multiple VMA which leads to multiple address transformation
|
||||
// functions. To support these multiple VMAS transformations and mappings TSAN
|
||||
@@ -302,6 +314,10 @@ enum MappingType {
|
||||
MAPPING_LO_APP_END,
|
||||
MAPPING_HI_APP_BEG,
|
||||
MAPPING_HI_APP_END,
|
||||
#ifdef TSAN_MID_APP_RANGE
|
||||
MAPPING_MID_APP_BEG,
|
||||
MAPPING_MID_APP_END,
|
||||
#endif
|
||||
MAPPING_HEAP_BEG,
|
||||
MAPPING_HEAP_END,
|
||||
MAPPING_APP_BEG,
|
||||
@@ -321,6 +337,10 @@ uptr MappingImpl(void) {
|
||||
#ifndef SANITIZER_GO
|
||||
case MAPPING_LO_APP_BEG: return Mapping::kLoAppMemBeg;
|
||||
case MAPPING_LO_APP_END: return Mapping::kLoAppMemEnd;
|
||||
# ifdef TSAN_MID_APP_RANGE
|
||||
case MAPPING_MID_APP_BEG: return Mapping::kMidAppMemBeg;
|
||||
case MAPPING_MID_APP_END: return Mapping::kMidAppMemEnd;
|
||||
# endif
|
||||
case MAPPING_HI_APP_BEG: return Mapping::kHiAppMemBeg;
|
||||
case MAPPING_HI_APP_END: return Mapping::kHiAppMemEnd;
|
||||
case MAPPING_HEAP_BEG: return Mapping::kHeapMemBeg;
|
||||
@@ -368,6 +388,17 @@ uptr LoAppMemEnd(void) {
|
||||
return MappingArchImpl<MAPPING_LO_APP_END>();
|
||||
}
|
||||
|
||||
#ifdef TSAN_MID_APP_RANGE
|
||||
ALWAYS_INLINE
|
||||
uptr MidAppMemBeg(void) {
|
||||
return MappingArchImpl<MAPPING_MID_APP_BEG>();
|
||||
}
|
||||
ALWAYS_INLINE
|
||||
uptr MidAppMemEnd(void) {
|
||||
return MappingArchImpl<MAPPING_MID_APP_END>();
|
||||
}
|
||||
#endif
|
||||
|
||||
ALWAYS_INLINE
|
||||
uptr HeapMemBeg(void) {
|
||||
return MappingArchImpl<MAPPING_HEAP_BEG>();
|
||||
@@ -422,6 +453,12 @@ bool GetUserRegion(int i, uptr *start, uptr *end) {
|
||||
*start = HeapMemBeg();
|
||||
*end = HeapMemEnd();
|
||||
return true;
|
||||
# ifdef TSAN_MID_APP_RANGE
|
||||
case 3:
|
||||
*start = MidAppMemBeg();
|
||||
*end = MidAppMemEnd();
|
||||
return true;
|
||||
# endif
|
||||
#else
|
||||
case 0:
|
||||
*start = AppMemBeg();
|
||||
@@ -463,6 +500,9 @@ template<typename Mapping>
|
||||
bool IsAppMemImpl(uptr mem) {
|
||||
#ifndef SANITIZER_GO
|
||||
return (mem >= Mapping::kHeapMemBeg && mem < Mapping::kHeapMemEnd) ||
|
||||
# ifdef TSAN_MID_APP_RANGE
|
||||
(mem >= Mapping::kMidAppMemBeg && mem < Mapping::kMidAppMemEnd) ||
|
||||
# endif
|
||||
(mem >= Mapping::kLoAppMemBeg && mem < Mapping::kLoAppMemEnd) ||
|
||||
(mem >= Mapping::kHiAppMemBeg && mem < Mapping::kHiAppMemEnd);
|
||||
#else
|
||||
@@ -611,6 +651,11 @@ uptr ShadowToMemImpl(uptr s) {
|
||||
if (s >= MemToShadow(Mapping::kLoAppMemBeg)
|
||||
&& s <= MemToShadow(Mapping::kLoAppMemEnd - 1))
|
||||
return (s / kShadowCnt) ^ Mapping::kAppMemXor;
|
||||
# ifdef TSAN_MID_APP_RANGE
|
||||
if (s >= MemToShadow(Mapping::kMidAppMemBeg)
|
||||
&& s <= MemToShadow(Mapping::kMidAppMemEnd - 1))
|
||||
return ((s / kShadowCnt) ^ Mapping::kAppMemXor) + Mapping::kMidShadowOff;
|
||||
# endif
|
||||
else
|
||||
return ((s / kShadowCnt) ^ Mapping::kAppMemXor) | Mapping::kAppMemMsk;
|
||||
#else
|
||||
|
||||
@@ -132,7 +132,12 @@ void CheckAndProtect() {
|
||||
|
||||
ProtectRange(LoAppMemEnd(), ShadowBeg());
|
||||
ProtectRange(ShadowEnd(), MetaShadowBeg());
|
||||
#ifdef TSAN_MID_APP_RANGE
|
||||
ProtectRange(MetaShadowEnd(), MidAppMemBeg());
|
||||
ProtectRange(MidAppMemEnd(), TraceMemBeg());
|
||||
#else
|
||||
ProtectRange(MetaShadowEnd(), TraceMemBeg());
|
||||
#endif
|
||||
// Memory for traces is mapped lazily in MapThreadTrace.
|
||||
// Protect the whole range for now, so that user does not map something here.
|
||||
ProtectRange(TraceMemBeg(), TraceMemEnd());
|
||||
|
||||
12
compiler-rt/test/tsan/pie_test.cc
Normal file
12
compiler-rt/test/tsan/pie_test.cc
Normal file
@@ -0,0 +1,12 @@
|
||||
// Check if tsan work with PIE binaries.
|
||||
// RUN: %clang_tsan %s -pie -fpic -o %t && %run %t
|
||||
|
||||
// Some kernels might map PIE segments outside the current segment
|
||||
// mapping defined for x86 [1].
|
||||
// [1] https://git.kernel.org/linus/d1fd836dcf00d2028c700c7e44d2c23404062c90
|
||||
|
||||
// UNSUPPORTED: x86
|
||||
|
||||
int main(void) {
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user