@@ -119,6 +119,9 @@ static const uint64_t kNetBSDKasan_ShadowOffset64 = 0xdfff900000000000;
119119static const uint64_t kPS_ShadowOffset64 = 1ULL << 40 ;
120120static const uint64_t kWindowsShadowOffset32 = 3ULL << 28 ;
121121static const uint64_t kEmscriptenShadowOffset = 0 ;
122+ static const uint64_t kAIXShadowOffset32 = 0x40000000 ;
123+ // 64-BIT AIX is not yet ready.
124+ static const uint64_t kAIXShadowOffset64 = 0x0a01000000000000ULL ;
122125
123126// The shadow memory space is dynamically allocated.
124127static const uint64_t kWindowsShadowOffset64 = kDynamicShadowSentinel ;
@@ -128,6 +131,8 @@ static const size_t kMaxStackMallocSize = 1 << 16; // 64K
128131static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3 ;
129132static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E ;
130133
134+ static const uint32_t kAIXHighBits = 6 ;
135+
131136const char kAsanModuleCtorName [] = " asan.module_ctor" ;
132137const char kAsanModuleDtorName [] = " asan.module_dtor" ;
133138static const uint64_t kAsanCtorAndDtorPriority = 1 ;
@@ -463,11 +468,14 @@ namespace {
463468
464469// / This struct defines the shadow mapping using the rule:
465470// / shadow = (mem >> Scale) ADD-or-OR Offset.
471+ // / However, on 64-bit AIX, we use HighBits to reduce the mapped address space:
472+ // / shadow = ((mem << HighBits) >> (HighBits + Scale)) + Offset
466473// / If InGlobal is true, then
467474// / extern char __asan_shadow[];
468475// / shadow = (mem >> Scale) + &__asan_shadow
469476struct ShadowMapping {
470477 int Scale;
478+ int HighBits;
471479 uint64_t Offset;
472480 bool OrShadowOffset;
473481 bool InGlobal;
@@ -487,6 +495,7 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize,
487495 bool IsLinux = TargetTriple.isOSLinux ();
488496 bool IsPPC64 = TargetTriple.getArch () == Triple::ppc64 ||
489497 TargetTriple.getArch () == Triple::ppc64le;
498+ bool IsAIX = TargetTriple.isOSAIX ();
490499 bool IsSystemZ = TargetTriple.getArch () == Triple::systemz;
491500 bool IsX86_64 = TargetTriple.getArch () == Triple::x86_64;
492501 bool IsMIPSN32ABI = TargetTriple.isABIN32 ();
@@ -526,14 +535,18 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize,
526535 Mapping.Offset = kWindowsShadowOffset32 ;
527536 else if (IsEmscripten)
528537 Mapping.Offset = kEmscriptenShadowOffset ;
538+ else if (IsAIX)
539+ Mapping.Offset = kAIXShadowOffset32 ;
529540 else
530541 Mapping.Offset = kDefaultShadowOffset32 ;
531542 } else { // LongSize == 64
532543 // Fuchsia is always PIE, which means that the beginning of the address
533544 // space is always available.
534545 if (IsFuchsia)
535546 Mapping.Offset = 0 ;
536- else if (IsPPC64)
547+ else if (IsAIX)
548+ Mapping.Offset = kAIXShadowOffset64 ;
549+ else if (IsPPC64 && !IsAIX)
537550 Mapping.Offset = kPPC64_ShadowOffset64 ;
538551 else if (IsSystemZ)
539552 Mapping.Offset = kSystemZ_ShadowOffset64 ;
@@ -592,13 +605,16 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize,
592605 // SystemZ, we could OR the constant in a single instruction, but it's more
593606 // efficient to load it once and use indexed addressing.
594607 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
595- !IsRISCV64 && !IsLoongArch64 &&
608+ !IsRISCV64 && !IsLoongArch64 && !IsAIX &&
596609 !(Mapping.Offset & (Mapping.Offset - 1 )) &&
597610 Mapping.Offset != kDynamicShadowSentinel ;
598611 bool IsAndroidWithIfuncSupport =
599612 IsAndroid && !TargetTriple.isAndroidVersionLT (21 );
600613 Mapping.InGlobal = ClWithIfunc && IsAndroidWithIfuncSupport && IsArmOrThumb;
601614
615+ if (IsAIX && LongSize == 64 )
616+ Mapping.HighBits = kAIXHighBits ;
617+
602618 return Mapping;
603619}
604620
@@ -1326,7 +1342,11 @@ static bool isUnsupportedAMDGPUAddrspace(Value *Addr) {
13261342
13271343Value *AddressSanitizer::memToShadow (Value *Shadow, IRBuilder<> &IRB) {
13281344 // Shadow >> scale
1329- Shadow = IRB.CreateLShr (Shadow, Mapping.Scale );
1345+ if (TargetTriple.isOSAIX () && TargetTriple.getArch () == Triple::ppc64)
1346+ Shadow = IRB.CreateLShr (IRB.CreateShl (Shadow, Mapping.HighBits ),
1347+ Mapping.Scale + Mapping.HighBits );
1348+ else
1349+ Shadow = IRB.CreateLShr (Shadow, Mapping.Scale );
13301350 if (Mapping.Offset == 0 ) return Shadow;
13311351 // (Shadow >> scale) | offset
13321352 Value *ShadowBase;
0 commit comments