[PATCH] D129621: [BPF] Handle anon record for CO-RE relocations

Yonghong Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 13 00:35:55 PDT 2022


yonghong-song created this revision.
yonghong-song added reviewers: ast, anakryiko.
Herald added a subscriber: hiraditya.
Herald added a project: All.
yonghong-song requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

When doing experiment in kernel, for kernel data structure sockptr_t
in CO-RE operation, I hit an assertion error. The sockptr_t definition
and usage look like below:

  #pragma clang attribute push (__attribute__((preserve_access_index)), apply_to = record)
  typedef struct {
        union {
                void    *kernel;
                void    *user;
        };  
        unsigned is_kernel : 1;
  } sockptr_t;
  #pragma clang attribute pop 
  int test(sockptr_t *arg) {
    return arg->is_kernel;
  }

The assertion error looks like

  clang: ../lib/Target/BPF/BPFAbstractMemberAccess.cpp:878: llvm::Value*
   {anonymous}::BPFAbstractMemberAccess::computeBaseAndAccessKey(llvm::CallInst*,
   {anonymous}::BPFAbstractMemberAccess::CallInfo&, std::__cxx11::string&,
   llvm::MDNode*&): Assertion `TypeName.size()' failed.

In this particular, the clang frontend attach the debuginfo metadata associated
with anon structure with the preserve_access_info IR intrinsic. But the first
debuginfo type has to be a named type so libbpf can have a sound start to
do CO-RE relocation.

Besides the above approach using pragma to push attribute, the below typedef/struct
definition can have preserve_access_index directly applying to the anon struct.

  typedef struct {
        union {
                void    *kernel;
                void    *user;
        };  
        unsigned is_kernel : 1;
  } __attribute__((preserve_access_index) sockptr_t;

This patch fixed the issue by preprocessing function argument/return types
and local variable types used by other CO-RE intrinsics. For any

  typedef struct/union { ... } typedef_name

an association of <anon struct/union, typedef> is recorded to replace
the IR intrinsic metadata 'anon struct/union' to 'typedef'.
It is possible that two different 'typedef' types may have identical
anon struct/union type. For such a case, the association will be
<anon struct/union, nullptr> to indicate the invalid case.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129621

Files:
  llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp
  llvm/test/CodeGen/BPF/CORE/anon-struct-argument-pragma.ll
  llvm/test/CodeGen/BPF/CORE/anon-union-localvar-attr.ll
  llvm/test/CodeGen/BPF/CORE/anon-union-localvar-pragma.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D129621.444174.patch
Type: text/x-patch
Size: 23845 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220713/5c1b5954/attachment.bin>


More information about the llvm-commits mailing list