[PATCH] D100567: BPF: emit debuginfo for Function of DeclRefExpr if requested

Yonghong Song via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 15 08:20:22 PDT 2021


yonghong-song created this revision.
yonghong-song added a reviewer: dblaikie.
yonghong-song added projects: debug-info, clang.
yonghong-song requested review of this revision.
Herald added a subscriber: cfe-commits.

Commit e3d8ee35e4ad <https://reviews.llvm.org/rGe3d8ee35e4adca664a9149536e0f0b3b0ceaeaeb> ("reland "[DebugInfo] Support to emit debugInfo
for extern variables"") added support to emit debugInfo for
extern variables if requested by the target. Currently, only
BPF target enables this feature by default.

As BPF ecosystem grows, callback function started to get
support, e.g., recently bpf_for_each_map_elem() is introduced
(https://lwn.net/Articles/846504/) with a callback function as an
argument. In the future we may have something like below as
a demonstration of use case :

  extern int do_work(int);
  long bpf_helper(void *callback_fn, void *callback_ctx, ...);
  long prog_main() {
      struct { ... } ctx = { ... };
      return bpf_helper(&do_work, &ctx, ...);
  }

Basically bpf helper may have a callback function and the
callback function is defined in another file. In this case,
we would like to know the debuginfo types for do_work(), so
the verifier can proper verify the safety of bpf_helper() call.
The do_work() might be a function from another file or from
the kernel.

For the following example,

  extern int do_work(int);
  long bpf_helper(void *callback_fn);
  long prog() {
      return bpf_helper(&do_work);
  }

Currently, there is no debuginfo generated for extern function do_work().
In the IR, we have,

  ...
  define dso_local i64 @prog() local_unnamed_addr #0 !dbg !7 {
  entry:
    %call = tail call i64 @bpf_helper(i8* bitcast (i32 (i32)* @do_work to i8*)) #2, !dbg !11
    ret i64 %call, !dbg !12
  }
  ...
  declare dso_local i32 @do_work(i32) #1
  ...

This patch added support for the above callback function use case, and
the generated IR looks like below:

  ...
  declare !dbg !17 dso_local i32 @do_work(i32) #1
  ...
  !17 = !DISubprogram(name: "do_work", scope: !1, file: !1, line: 1, type: !18, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
  !18 = !DISubroutineType(types: !19)
  !19 = !{!20, !20}
  !20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D100567

Files:
  clang/lib/CodeGen/CGExpr.cpp
  clang/test/CodeGen/debug-info-extern-callback.c


Index: clang/test/CodeGen/debug-info-extern-callback.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/debug-info-extern-callback.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -x c -debug-info-kind=limited -triple bpf-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+extern int do_work(int);
+long bpf_helper(void *callback_fn);
+long prog() {
+	    return bpf_helper(&do_work);
+}
+
+// CHECK: declare !dbg ![[FUNC:[0-9]+]] i32 @do_work(i32)
+// CHECK: ![[FUNC]] = !DISubprogram(name: "do_work"
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -2833,8 +2833,19 @@
     return LV;
   }
 
-  if (const auto *FD = dyn_cast<FunctionDecl>(ND))
-    return EmitFunctionDeclLValue(*this, E, FD);
+  if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
+    LValue LV = EmitFunctionDeclLValue(*this, E, FD);
+
+    // Emit debuginfo for the function declaration if the target wants to.
+    if (getContext().getTargetInfo().allowDebugInfoForExternalVar()) {
+      CGDebugInfo *DI = CGM.getModuleDebugInfo();
+      auto *Fn = dyn_cast<llvm::Function>(LV.getPointer(*this));
+      if (DI && Fn)
+        DI->EmitFunctionDecl(FD, FD->getLocation(), T, Fn);
+    }
+
+    return LV;
+  }
 
   // FIXME: While we're emitting a binding from an enclosing scope, all other
   // DeclRefExprs we see should be implicitly treated as if they also refer to


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D100567.337774.patch
Type: text/x-patch
Size: 1511 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210415/01dd9332/attachment.bin>


More information about the cfe-commits mailing list