[PATCH] Fix const pointer assignment trick on clang 9+
余生与君
lovesykun at gmail.com
Sat Oct 9 02:17:02 UTC 2021
Tried, not working.
On Fri, Oct 8, 2021 at 10:21 PM Denys Vlasenko <vda.linux at googlemail.com> wrote:
>
> On Fri, Oct 8, 2021 at 10:39 AM 余生与君 <lovesykun at gmail.com> wrote:
> > On Thu, Oct 7, 2021 at 9:48 PM Denys Vlasenko <vda.linux at googlemail.com> wrote:
> > > Can you try something more? E.g. (in current git):
> > >
> > > #define ASSIGN_CONST_PTR(p, v) do { \
> > > *(void**)not_const_pp(&p) = (void*)(v); \
> > > /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \
> > > barrier(); \
> > > + sleep(0); \
> > > } while (0)
> >
> > Cool! Sleep(0) does the magic!
> >
> > ADRP X21, #ash_ptr_to_globals_misc_ptr at PAGE
> > LDR X21, [X21,#ash_ptr_to_globals_misc_ptr at PAGEOFF]
> > MOV X8, X21
> > STR X0, [X8]
> > MOV W0, WZR
> > BL sleep
> > LDR X21, [X21]
> >
> >
> > And further investigation shows that a dummy function can also do this trick!
> >
> > hack.c:
> > void clang_barrier() {
> > }
>
> We don't need the function call. We only need to tell clang that
> a lot of registers are "needed" for something.
> This "something" ideally should be nothing.
>
> Can you try this?
>
> #if defined(__clang_major__) && __clang_major__ >= 9
> /* Clang/llvm drops assignment to "constant" storage. Silently.
> * Needs serious convincing to not eliminate the store.
> */
> static ALWAYS_INLINE void register_barrier(void)
> {
> int r0, r1, r2, r3, r4, r5;
> asm volatile (
> "# clobber 6 registers"
> : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(r4), "=r"(r5)
> : "0"(r1), "1"(r1), "2"(r2), "3"(r3), "4"(r4), "5"(r5)
> : "memory"
>
> );
> }
> static ALWAYS_INLINE void* not_const_pp(const void *p)
> {
> void *pp;
> asm volatile (
> "# forget that p points to const"
> : /*outputs*/ "=r" (pp)
> : /*inputs*/ "0" (p)
> );
> return pp;
> }
> #define ASSIGN_CONST_PTR(p, v) do { \
> *(void**)not_const_pp(&p) = (void*)(v); \
> register_barrier();
> } while (0)
> #else
> static ALWAYS_INLINE void* not_const_pp(const void *p) { return (void*)p; }
> #define ASSIGN_CONST_PTR(p, v) do { \
> *(void**)not_const_pp(&p) = (void*)(v); \
> /* At least gcc 3.4.6 on mipsel needs optimization barrier */ \
> barrier(); \
> } while (0)
> #endif
>
> If this works, experiment what minimum number of rN
> in register_barrier() is actually needed to placate clang.
More information about the busybox
mailing list