[cfe-dev] support __attribute__((weak)) for non-primitive types

Aaron Ballman via cfe-dev cfe-dev at lists.llvm.org
Tue Aug 24 11:30:29 PDT 2021

On Tue, Aug 24, 2021 at 1:18 AM Y Song <ys114321 at gmail.com> wrote:
> Hi,
> This is a BPF use case. We would like to check whether
> __attribute__((weak)) support for non-primitive types would be
> possible in clang or not. For example, if we have two types like
>    struct t { int a; } __attribute__((weak));
>    struct t { int a; };
>    typedef unsigned __u32;
>    typedef unsigned __u32 __attribute__((weak));
> the compilation should not fail. It should just ignore weak definitions.
> In BPF, to support CO-RE (compile once and run everywhere), we
> generate a *generic* vmlinux.h
> (https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html)
> which is included in the bpf program. The bpf loader (libbpf) will
> adjust field offsets properly based on host record layout so the same
> program can run on different kernels which may have different record
> layouts.
> But vmlinux.h does not support macros (and simple static inline helper
> functions in kernel header files). Currently, users need to define
> these macros and static inline functions explicitly in their bpf
> program. What we are thinking is to permit users to include kernel
> header files containing these macros/static inline functions. But this
> may introduce duplicated types as these types have been defined in
> vmlinux.h.
> For example, we may have:
>     socket.h:
>         struct socket { ... };
>         #define TCP    6
>     vmlinux.h:
>         struct socket { ... };
>     bpf.c:
>         #include <socket.h>
>         #include <vmlinux.h>
>         ... TCP ...
> In this case, struct "socket" is defined twice. If we can have something like
>     bpf.c:
>       #pragma clang attribute push (__attribute__((weak)), apply_to = record)
>       #include <socket.h>
>       #pragma clang attribute pop
>       #include <vmlinux.h>
>         ... TCP ...
> Then bpf program can get header file macro definitions without copying
> explicitly.
> We need support for "apply_to = typedef" in the above pragma, so we
> can deal with typedef types as well.
> Another issue is related to what if two types are not compatible. For example,
>     struct t { int a; } __attribute__((weak));
>     struct t { int a; int b; };
> I think we could have a flag to control whether we allow incompatible
> weak type or not.
> It would be good if I can get some suggestions/directions on whether
> such a feature is possible or not for clang frontend.

One concern I have is that __attribute__((weak)) originally came from
GCC and I don't believe GCC supports this functionality. Are you
floating this idea by them as well to see if they're on board with it?

As I understand it, this attribute is more about symbols that have
been exported and how the linker interacts with them. Does the same
concept apply here to type declarations? If not, that may suggest we
should use a separate attribute so as not to confuse the semantics.


> Thanks,
> Yonghong

More information about the cfe-dev mailing list