1 This patch was developed in house for Bug 21658934. Python PyObject_Free()
2 implementation relies on being able to read memory that might not belong to
3 the current buffer. When ADIHEAP is enabled, this is detected as a violation.
4 Use an explicit nonfaulting load to ignore the ADI tag.
6 This patch should now work with both Studio and gcc compilers (and possibly
7 many others). It might be pushed upstream.
9 --- Python-3.9.0/Objects/obmalloc.c
10 +++ Python-3.9.0/Objects/obmalloc.c
11 @@ -1407,6 +1407,38 @@ obmalloc controls. Since this test is n
12 extremely desirable that it be this fast.
17 + * Py_ADDRESS_IN_RANGE needs to access memory that might be arbitrarily
18 + * tagged by an ADI aware allocator. The use of a nonfaulting load
19 + * guarantees that the read will succeed.
23 +/* Studio can use built-in nonfaulting load instruction for vis.h */
25 +#define POOL_INDEX(x) __vis_ldswa_ASI_PNF((void*)x)
27 +#else /* __SUNPRO_C */
29 + * GCC doesn't have similar instruction built-in, but it can use
30 + * following assembly code to do the same.
33 +static inline int vis_ldswa_ASI_PNF(void *arg);
35 +int vis_ldswa_ASI_PNF(void *arg) {
37 + __asm__ ("ldswa [%1]0x82,%0" : "=r" (res) : "r" (arg));
40 +#define POOL_INDEX(x) vis_ldswa_ASI_PNF((void*)x)
42 +#endif /* __SUNPRO_C */
43 +#else /* __sparcv9 */
44 +#define POOL_INDEX(x) (*(x))
45 +#endif /* __sparcv9 */
47 static bool _Py_NO_SANITIZE_ADDRESS
48 _Py_NO_SANITIZE_THREAD
49 _Py_NO_SANITIZE_MEMORY
50 @@ -1417,7 +1449,7 @@ address_in_range(void *p, poolp pool)
51 // another thread may be concurrently modifying the value without holding
52 // the GIL. The following dance forces the compiler to read pool->arenaindex
54 - uint arenaindex = *((volatile uint *)&pool->arenaindex);
55 + uint arenaindex = (uint)POOL_INDEX((volatile uint *)&pool->arenaindex);
56 return arenaindex < maxarenas &&
57 (uintptr_t)p - arenas[arenaindex].address < ARENA_SIZE &&
58 arenas[arenaindex].address != 0;