Skip to content

Bpf extern debuginfo#152899

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

Bpf extern debuginfo#152899
altugbozkurt07 wants to merge 3 commits intorust-lang:mainfrom
altugbozkurt07:bpf-extern-debuginfo

Conversation

@altugbozkurt07
Copy link

@altugbozkurt07 altugbozkurt07 commented Feb 20, 2026

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
Collaborator

rustbot commented Feb 20, 2026

Some changes occurred in compiler/rustc_attr_parsing

cc @jdonszelmann, @JonathanBrouwer

@rustbot
Copy link
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
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
Contributor

Choose a reason for hiding this comment

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

This seems duplicated

}

// Handle foreign static items (extern declarations)
if self.tcx.is_foreign_item(def_id) {
Copy link
Contributor

Choose a reason for hiding this comment

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

With this

Copy link
Author

Choose a reason for hiding this comment

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

Are you talking about the comment being duplicated, or the code block where we handle foreign items for callee and consts ? Do you want me to create a unified function for this code block and use it instead ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Are you talking about the comment being duplicated, or the code block where we handle foreign items for callee and consts ?

Pretty sure she means the latter.

Do you want me to create a unified function for this code block and use it instead ?

Also pretty sure that's what you should do.

Choose a reason for hiding this comment

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

Thanks for the feedback, appreciated!

Copy link
Author

Choose a reason for hiding this comment

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

Hey there, the two blocks do share the same outer structure (set_link_section + BPF arch guard), but I'm wondering if unification is worth the trade-off at this scale — the only shared logic is essentially a single if arch == Bpf check. The options I see are either a closure parameter or an enum, and I'm not sure either adds more clarity than the 3 lines of repeated structure they'd remove. That said, happy to do it if you think the consistency is still valuable — just wanted to flag the consideration before going ahead.

/// 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
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
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
Collaborator

rustbot commented Feb 20, 2026

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

@altugbozkurt07
Copy link
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
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
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
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
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
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
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
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
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
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
Author

Choose a reason for hiding this comment

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

done

@jieyouxu jieyouxu marked this pull request as draft February 21, 2026 09:17
@apiraino
Copy link
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.

Altug Bozkurt added 3 commits February 28, 2026 18:45
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).
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.
@altugbozkurt07
Copy link
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.

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