On Wed, Sep 29, 2021 at 11:37 AM LoveSy <[email protected]> wrote:
>
> From: YU Jincheng <[email protected]>
>
> - clang 9+ will load the const pointer first before the const
>   pointer assignment trick and thus cause null pointer defer.
> - This patch creates a shadow variable to prevent the above from
>   happening for clang 9+.
> - Also, this patch applies `BB_GLOBAL_CONST` to all variables
>   using the same trick, allowing archs or toolchains having the
>   same issue to bypass this trick correctly.
>
> This patch fixes https://bugs.busybox.net/show_bug.cgi?id=14231
> and https://bugs.busybox.net/show_bug.cgi?id=14236
>
> Co-authored-by: canyie <[email protected]>
> Signed-off-by: YU Jincheng <[email protected]>
....
> +#define ASSIGN_CONST_PTR(p, v) \
> +_Pragma("clang diagnostic push"); \
> +_Pragma("clang diagnostic ignored \"-Wshadow\""); \
> +       __typeof__(p) p = ({*(void**)not_const_pp(&p) = (void*)(v);});
> +_Pragma("clang diagnostic pop")
> +#endif

So, you observe that

    *(void**)not_const_pp(&p) = (void*)(v);

does not work, but

    void *p = ({*(void**)not_const_pp(&p) = (void*)(v);});

(where p is a dummy, unused variable) works?
This is kind of surprising, since dummy variable can be completely
eliminated by the optimizer, making above statements equivalent.
(Also, why ({...;})? Does
    void *p = *(void**)not_const_pp(&p) = (void*)(v);
work too?)

Can we try something more stable?
For example, try this:

-static ALWAYS_INLINE void* not_const_pp(const void *p)
+static ALWAYS_INLINE volatile void* not_const_pp(const void *p)
 {
-        void *pp;
+        volatile void *pp;

or this:

          *(void *volatile *)not_const_pp(&p) = (void*)(v);

(we say to compiler that this pointer is to volatile
storage, specifically a volatile pointer,
"do not optimize the store").
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to