Skip to content

Generate debug info for BPF extern declarations#152899

Draft
altugbozkurt07 wants to merge 3 commits intorust-lang:mainfrom
altugbozkurt07:bpf-extern-debuginfo
Draft

Generate debug info for BPF extern declarations#152899
altugbozkurt07 wants to merge 3 commits intorust-lang:mainfrom
altugbozkurt07:bpf-extern-debuginfo

Conversation

@altugbozkurt07
Copy link
Copy Markdown

@altugbozkurt07 altugbozkurt07 commented Feb 20, 2026

View all comments

BPF ksyms program's requires BTF metadata to be used by the loader to resolve the extern items against the running kernel during load time. For this the rustc needs to emit debug information for extern declarations so that the llvm backend could generate the proper BTF entries. This PR addresses :

This PR enables ksyms support for BPF programs written in Rust by allowing #[link_section]
on ForeignStatic and ForeignFn, adding an FFI wrapper for
LLVMDIBuilderCreateGlobalVariableExpression that exposes isDefinition, and emitting
debug info for BPF extern function and variable declarations (gated to Arch::Bpf).

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Feb 20, 2026

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Feb 20, 2026

Failed to set assignee to @davidtwco: invalid assignee

Note: Only org members with at least the repository "read" role, users with write permissions, or people who have commented on the PR may be assigned.

@rustbot rustbot added A-attributes Area: Attributes (`#[…]`, `#![…]`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 20, 2026
@rust-log-analyzer

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@jdonszelmann jdonszelmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some simple comments. May I ask you whether you generated your pr description (and/or code with generative AI). In that case could you please declare so. It seems so and I don't want to waste my time.

View changes since this review


cx.assume_dso_local(llfn, true);

// Handle foreign function items (extern declarations)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems duplicated

/// If `llfn` is provided, the DISubprogram will be attached to the LLVM function.
///
/// Returns `None` if debug info is not enabled.
pub(crate) fn dbg_scope_fn_decl(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to name this something with foreign function in the name

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 20, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Feb 20, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@altugbozkurt07
Copy link
Copy Markdown
Author

altugbozkurt07 commented Feb 20, 2026

Some simple comments. May I ask you whether you generated your pr description (and/or code with generative AI). In that case could you please declare so. It seems so and I don't want to waste my time.

View changes since this review

Yes, i used generative ai tooling when working on this issue, is that a problem or against a policy that i am not aware of?

I did test out the changes i made manually and review all of the work thoroughly in my local setup, so i did not just vibe coded this if that is what you are asking.

@jdonszelmann
Copy link
Copy Markdown
Contributor

jdonszelmann commented Feb 20, 2026

With mention it can be ok, wasting reviewer time is not. I don't like this pr description, I'd say it's against policy, the changes mostly look fine (as far as I'm knowledgeable in these parts of the compiler) though I don't like the duplication. I recommend you do a thorough pass reviewing your own code first and then we take a look. We're all volunteers here, I don't think many of us will enjoy reviewing this pr description not will I use ai to summarize it or whatever, why is the description even there in that case. Maybe the pr itself is fine, but yea, give it a thoroughmanual review first, spot things like the duplication I marked. If you think it's to a point that you'd manually want to review it, then we can take a look for you.

@altugbozkurt07
Copy link
Copy Markdown
Author

Okay, thanks for the feedback! i will take a thorough review and trim down the description as well. Best!!

Comment on lines +1412 to +1413
global,
None,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't remove the comments that were there before.

Suggested change
global,
None,
global, // (value)
None, // (decl)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


// Custom wrapper that exposes the IsDefined parameter, which the standard
// LLVM-C API (LLVMDIBuilderCreateGlobalVariableExpression) hard-codes to true.
// This is needed for BPF/BTF extern declarations where isDefinition must be false.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rest of functions don't seem to have these kind of comments. Not sure what's the Rust team's take on adding them, but even if we want to introduce them, I don't think we want to mention the details like "This is needed for BPF/BTF extern declarations". This function is a wrapper over an LLVM method, and as such should just describe that method, not the reason you added it here.

If we want any description here, then we want something going straight to the point - what this wrapper does.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i trimmed it down further and removed bpf specific mentions.


// Custom wrapper that exposes the IsDefined parameter which the standard
// LLVM-C API (LLVMDIBuilderCreateGlobalVariableExpression) hard-codes to true.
// This is needed for BPF/BTF extern declarations where isDefinition must be false.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +48 to +50
/// The `is_definition` parameter controls whether this is a definition (`true`)
/// or a declaration (`false`). For extern statics (e.g., BPF ksyms), use `false`
/// since they are declarations resolved at load time, not definitions.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if mentioning ksyms is necessary here. I think just mentioning the definition vs declaration difference is enough. People can use git blame if they want to know more about the reasons of introduction.

Suggested change
/// The `is_definition` parameter controls whether this is a definition (`true`)
/// or a declaration (`false`). For extern statics (e.g., BPF ksyms), use `false`
/// since they are declarations resolved at load time, not definitions.
/// The `is_definition` parameter controls whether this is a definition (`true`)
/// or a declaration (`false`).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you've addressed this comment, but applied the change to the wrong commit. Could you apply the change to this exact commit using git rebase -i?

@jieyouxu jieyouxu marked this pull request as draft February 21, 2026 09:17
@apiraino
Copy link
Copy Markdown
Contributor

Okay, thanks for the feedback! i will take a thorough review and trim down the description as well. Best!!

@altugbozkurt07 thank you for contributing to this project. To help you getting your bearings right, feel free to read our contribution guidelines and our etiquette with useful tips and expectations from new contributors.

@altugbozkurt07 altugbozkurt07 force-pushed the bpf-extern-debuginfo branch 2 times, most recently from 1bbfe49 to 7b915e5 Compare February 21, 2026 15:04
@rust-log-analyzer

This comment has been minimized.

@altugbozkurt07
Copy link
Copy Markdown
Author

i have manually and thoroughly reviewed the PR, and did some minor changes. Now there is only that duplicate if block thing that i havent resolved yet and asked for one last opinion before proceeding. In the meantime i would appreciate a review of my PR.

@vadorovsky
Copy link
Copy Markdown
Contributor

Can you please come up with a better title? Perhaps use the one from the last commit - Generate debug info for BPF extern declarations.

@altugbozkurt07 altugbozkurt07 changed the title Bpf extern debuginfo Generate debug info for BPF extern declarations Mar 13, 2026
@altugbozkurt07
Copy link
Copy Markdown
Author

Can you please come up with a better title? Perhaps use the one from the last commit - Generate debug info for BPF extern declarations.

I changed it into something more descriptive now, is that okay?

Comment on lines +48 to +50
/// The `is_definition` parameter controls whether this is a definition (`true`)
/// or a declaration (`false`). For extern statics (e.g., BPF ksyms), use `false`
/// since they are declarations resolved at load time, not definitions.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you've addressed this comment, but applied the change to the wrong commit. Could you apply the change to this exact commit using git rebase -i?

///
/// The `is_definition` parameter controls whether this is a definition (`true`)
/// or a declaration (`false`). For extern statics (e.g., BPF ksyms), use `false`
/// since they are declarations resolved at load time, not definitions.
Copy link
Copy Markdown
Contributor

@vadorovsky vadorovsky Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

This should be applied to the previous commit (Add FFI wrapper to expose isDefinition in DIBuilder).

// This is needed for BPF/BTF extern declarations where isDefinition must be false.
// Wraps DIBuilder::createGlobalVariableExpression. Unlike the LLVM-C API
// (LLVMDIBuilderCreateGlobalVariableExpression), this exposes the IsDefined
// parameter instead of hard-coding it to true.
Copy link
Copy Markdown
Contributor

@vadorovsky vadorovsky Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

This should be applied to the previous commit (Add FFI wrapper to expose isDefinition in DIBuilder).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be okay now

@@ -1,6 +1,4 @@
// Verifies that #[link_section] works on foreign (extern) items.
// This is useful for BPF ksyms/kfuncs where extern declarations
// need to be placed in specific sections for BTF generation.
Copy link
Copy Markdown
Contributor

@vadorovsky vadorovsky Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

This should be applied to the previous commit (Add FFI wrapper to expose isDefinition in DIBuilder).

}
}

fn get_function_signature(
Copy link
Copy Markdown
Contributor

@vadorovsky vadorovsky Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

View changes since the review

Why did you move this method? Please leave it where it was. It's a part of a trait.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed it to re-use it to get signature of foreign functions, thought it would make sense to place it in a way i can re-use it. Now i reverted it, and instead created a stripped in-lined version that is much smaller and covers our use case. Let me know what you think

Altug Bozkurt added 2 commits April 10, 2026 14:37
Extend the existing stable `#[link_section]` attribute to work on
`extern` statics and functions. This adds `ForeignStatic` and
`ForeignFn` to the attribute's allowed targets, consistent with
other foreign-item attributes like `link_name` and `linkage`.

This is useful for BPF programs that need extern declarations
placed in specific ELF sections for BTF generation, and for linker
scripts on other targets.
The LLVM-C API function `LLVMDIBuilderCreateGlobalVariableExpression`
hard-codes `isDefinition=true`. The C++ `DIBuilder` method accepts
an `isDefined` parameter, but the C binding does not expose it and
there is no way to modify the flag after creation since LLVM metadata
nodes are immutable.

Add `LLVMRustDIBuilderCreateGlobalVariableExpression` to expose this
parameter. This is needed for BPF extern declarations that require
`isDefinition: false` in their DIGlobalVariable for BTF generation.

Update `create_static_variable` in di_builder.rs to accept and
forward the new `is_definition` parameter, and update all existing
callers to pass `true` (preserving current behavior).
@rust-log-analyzer

This comment has been minimized.

Emit debug info metadata for extern statics and functions on BPF
targets. Extern statics get DIGlobalVariable with isDefinition: false,
and extern functions get DISubprogram without SPFlagDefinition. This
metadata is required by BPF toolchains (bpf-linker, LLVM) to produce
BTF entries that the kernel verifier uses to resolve ksyms and kfuncs
at program load time.

The implementation follows clang's approach: debug info generation is
gated to BPF targets only via Arch::Bpf checks at the call sites,
while the functions themselves handle dbg_cx and debuginfo level
checks internally.

Refactor build_global_var_di_node to share a common inner function
with the new build_extern_static_di_node, differing only in
is_local_to_unit and is_definition flags.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants