[llvm-dev] put "str" in __attribute__((annotate("str"))) to dwarf

Aaron Ballman via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 10 12:09:58 PDT 2021


On Thu, Jun 10, 2021 at 2:45 PM Y Song <ys114321 at gmail.com> wrote:
>
> On Thu, Jun 10, 2021 at 11:29 AM David Blaikie <dblaikie at gmail.com> wrote:
> >
> > On Thu, Jun 10, 2021 at 11:09 AM Y Song <ys114321 at gmail.com> wrote:
> >>
> >> On Thu, Jun 10, 2021 at 10:05 AM David Blaikie <dblaikie at gmail.com> wrote:
> >> >
> >> > (Crossposting to cfe-dev because this includes a proposal for a new C/C++ level attribute)
> >> >
> >> > These attributes are all effectively hand-written (with or without macros) in the input source? None of them are derived by the compiler frontend based on other characteristics?
> >>
> >> Yes, they are hand-written in the input source and fit into the clang
> >> compiler. They are not derived inside the clang/llvm.
> >
> >
> > Good to know/understand.
> >
> >>
> >>
> >> >
> >> > And I'm guessing maybe we'd want the name to be a bit narrower, like bpf_annotate, perhaps - taking such a generic term as "annotate" in the global attribute namespace seems fairly bold for what's currently a fairly narrow use case. +Aaron Ballman thoughts on this?
> >>
> >> I am okay with something like bpf_annotate as the existing annotate
> >> attribute will generate global variables or codes for annotations
> >> which is unnecessary for bpf use case,
> >> although the overhead should be quite small.
> >
> >
> > Ah, there's an existing annotate attribute you're proposing leveraging/reusing that? Got a pointer to the documentation for that? I don't see it documented here: https://clang.llvm.org/docs/AttributeReference.html
>
> Looks like this attribute is not well documented.

Correct -- it's an ancient attribute that predates us documenting
attributes at all.

> I forgot how I found it. But below is a public blog on how it could be used:
>    https://blog.quarkslab.com/implementing-a-custom-directive-handler-in-clang.html
> I then went to
>   clang/include/clang/Basic/Attr.td
> and found
>
> def Annotate : InheritableParamAttr {
>   let Spellings = [Clang<"annotate">];
>   let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">];
>   // Ensure that the annotate attribute can be used with
>   // '#pragma clang attribute' even though it has no subject list.
>   let AdditionalMembers = [{
>   static AnnotateAttr *Create(ASTContext &Ctx, llvm::StringRef Annotation, \
>               const AttributeCommonInfo &CommonInfo) {
>     return AnnotateAttr::Create(Ctx, Annotation, nullptr, 0, CommonInfo);
>   }
>   static AnnotateAttr *CreateImplicit(ASTContext &Ctx, llvm::StringRef
> Annotation, \
>               const AttributeCommonInfo &CommonInfo = {SourceRange{}}) {
>     return AnnotateAttr::CreateImplicit(Ctx, Annotation, nullptr, 0,
> CommonInfo);
>   }
>   }];
>   let PragmaAttributeSupport = 1;
>   let Documentation = [Undocumented];
> }
>
> and tried to use it for places BPF cares about and it all covers.

I don't think it's a good idea to use annotate for BPF needs. The
basic idea behind annotate is that it's a way to pass arbitrary string
(and starting very recently, other kinds of constant expressions) from
the frontend to the backend. So it's a general-purpose tool that's
used for one-off situations. As an example, attribute plugins will use
it because they cannot currently create their own semantic attribute
easily, and I think the static analyzer may make use of the feature as
well. Because the BPF needs are so specific, I think it'd be better to
use an attribute dedicated to those needs rather than using a
general-purpose attribute like annotate -- this will reduce the
likelihood of conflicts with the other creative uses people put
annotate to.

> BTW, the above attr definition does say Undocumented.

Yeah, the build requires there to be some documentation for every
attribute, and Undocumented is what we use for attributes that we
elect not to document because they're implementation details (rarely)
or have failed to document yet (much more common).

HTH!

~Aaron

>
> >
> >>
> >>
> >> >
> >> >
> >> > On Wed, Jun 9, 2021 at 7:42 PM Y Song <ys114321 at gmail.com> wrote:
> >> >>
> >> >> Hi,
> >> >>
> >> >> This feature is for the BPF community. The detailed use case is
> >> >> described in https://reviews.llvm.org/D103549. And I have crafted a
> >> >> WIP patch https://reviews.llvm.org/D103667 which implements necessary
> >> >> frontend and codegen (plus others) to show the scope of the work.
> >> >>
> >> >> To elaborate the use case a little bit more. Basically, we want to put
> >> >> some annotations into variables (include parameters), functions,
> >> >> structure/union types and structure/union members. The string
> >> >> arguments in annotations will not
> >> >> be interpreted  inside the compiler. The compiler should just emit
> >> >> these annotations into dwarf. Currently in the linux build system,
> >> >> pahole will convert dwarf to BTF which will encode these annotation
> >> >> strings into BTF. The following is a C example how annotations look
> >> >> like at source level:
> >> >>
> >> >> $ cat t1.c
> >> >> /* a pointer pointing to user memory */
> >> >> #define __user __attribute__((annotate("user")))
> >> >> /* a pointer protected by rcu */
> >> >> #define __rcu __attribute__((annotate("rcu")))
> >> >> /* the struct has some special property */
> >> >> #define __special_struct __attribute__((annotate("special_struct")))
> >> >> /* sock_lock is held for the function */
> >> >> #define __sock_lock_held __attribute((annotate("sock_lock_held")))
> >> >> /* the hash table element type is socket */
> >> >> #define __special_info __attribute__((annotate("elem_type:socket")))
> >> >>
> >> >> struct hlist_node;
> >> >> struct hlist_head {
> >> >>   struct hlist_node *prev;
> >> >>   struct hlist_node *next;
> >> >> } __special_struct;
> >> >> struct hlist {
> >> >>    struct hlist_head head __special_info;
> >> >> };
> >> >>
> >> >> extern void bar(struct hlist *);
> >> >> int foo(struct hlist *h,  int *a __user, int *b __rcu) __sock_lock_held {
> >> >>   bar(h);
> >> >>   return *a + *b;
> >> >> }
> >> >>
> >> >> In https://reviews.llvm.org/D103667, I implemented a LLVM extended attribute
> >> >> DWARF_AT_LLVM_annotations. But this might not be the right thing to do
> >> >> as it is not clear whether there are use cases beyond BPF.
> >> >> David suggested that we discuss this in llvm-dev to get consensus on
> >> >> how this feature may be supported in LLVM. Hence this email.
> >> >>
> >> >> Please share your comments, suggestions on how to support this feature
> >> >> in LLVM. Thanks!
> >> >>
> >> >> Yonghong


More information about the llvm-dev mailing list