@@ -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 ;
@@ -468,6 +473,7 @@ namespace {
468473// / shadow = (mem >> Scale) + &__asan_shadow
469474struct ShadowMapping {
470475 int Scale;
476+ int HighBits;
471477 uint64_t Offset;
472478 bool OrShadowOffset;
473479 bool InGlobal;
@@ -487,6 +493,7 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize,
487493 bool IsLinux = TargetTriple.isOSLinux ();
488494 bool IsPPC64 = TargetTriple.getArch () == Triple::ppc64 ||
489495 TargetTriple.getArch () == Triple::ppc64le;
496+ bool IsAIX = TargetTriple.isOSAIX ();
490497 bool IsSystemZ = TargetTriple.getArch () == Triple::systemz;
491498 bool IsX86_64 = TargetTriple.getArch () == Triple::x86_64;
492499 bool IsMIPSN32ABI = TargetTriple.isABIN32 ();
@@ -526,14 +533,18 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize,
526533 Mapping.Offset = kWindowsShadowOffset32 ;
527534 else if (IsEmscripten)
528535 Mapping.Offset = kEmscriptenShadowOffset ;
536+ else if (IsAIX)
537+ Mapping.Offset = kAIXShadowOffset32 ;
529538 else
530539 Mapping.Offset = kDefaultShadowOffset32 ;
531540 } else { // LongSize == 64
532541 // Fuchsia is always PIE, which means that the beginning of the address
533542 // space is always available.
534543 if (IsFuchsia)
535544 Mapping.Offset = 0 ;
536- else if (IsPPC64)
545+ else if (IsAIX)
546+ Mapping.Offset = kAIXShadowOffset64 ;
547+ else if (IsPPC64 && !IsAIX)
537548 Mapping.Offset = kPPC64_ShadowOffset64 ;
538549 else if (IsSystemZ)
539550 Mapping.Offset = kSystemZ_ShadowOffset64 ;
@@ -592,13 +603,16 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize,
592603 // SystemZ, we could OR the constant in a single instruction, but it's more
593604 // efficient to load it once and use indexed addressing.
594605 Mapping.OrShadowOffset = !IsAArch64 && !IsPPC64 && !IsSystemZ && !IsPS &&
595- !IsRISCV64 && !IsLoongArch64 &&
606+ !IsRISCV64 && !IsLoongArch64 && !IsAIX &&
596607 !(Mapping.Offset & (Mapping.Offset - 1 )) &&
597608 Mapping.Offset != kDynamicShadowSentinel ;
598609 bool IsAndroidWithIfuncSupport =
599610 IsAndroid && !TargetTriple.isAndroidVersionLT (21 );
600611 Mapping.InGlobal = ClWithIfunc && IsAndroidWithIfuncSupport && IsArmOrThumb;
601612
613+ if (IsAIX && LongSize == 64 )
614+ Mapping.HighBits = kAIXHighBits ;
615+
602616 return Mapping;
603617}
604618
@@ -1326,7 +1340,11 @@ static bool isUnsupportedAMDGPUAddrspace(Value *Addr) {
13261340
13271341Value *AddressSanitizer::memToShadow (Value *Shadow, IRBuilder<> &IRB) {
13281342 // Shadow >> scale
1329- Shadow = IRB.CreateLShr (Shadow, Mapping.Scale );
1343+ if (TargetTriple.isOSAIX () && TargetTriple.getArch () == Triple::ppc64)
1344+ Shadow = IRB.CreateLShr (IRB.CreateShl (Shadow, Mapping.HighBits ),
1345+ Mapping.Scale + Mapping.HighBits );
1346+ else
1347+ Shadow = IRB.CreateLShr (Shadow, Mapping.Scale );
13301348 if (Mapping.Offset == 0 ) return Shadow;
13311349 // (Shadow >> scale) | offset
13321350 Value *ShadowBase;
0 commit comments