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

Y Song via cfe-dev cfe-dev at lists.llvm.org
Mon Aug 23 16:17:00 PDT 2021


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.

Thanks,

Yonghong


More information about the cfe-dev mailing list