Skip to content

Add support for custom attributes#2866

Merged
pvdrz merged 1 commit intorust-lang:mainfrom
mkroening:attributes
Sep 3, 2024
Merged

Add support for custom attributes#2866
pvdrz merged 1 commit intorust-lang:mainfrom
mkroening:attributes

Conversation

@mkroening
Copy link
Copy Markdown
Contributor

This adds support for custom attributes:

  • ParseCallbacks::add_attributes(&self, info: &AttributeInfo<'_>) -> Vec<TokenStream>
  • --with-attribute-custom <CUSTOM>
  • --with-attribute-custom-struct <CUSTOM>
  • --with-attribute-custom-enum <CUSTOM>
  • --with-attribute-custom-union <CUSTOM>

The implementation is very similar to the custom derives functionality. One thing I am not sure about is returning Vec<TokenStream> instead of Vec<String>, but that seemed natural to me.

Fixes #2520

Copy link
Copy Markdown
Contributor

@pvdrz pvdrz left a comment

Choose a reason for hiding this comment

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

Hi @mkroening sorry for the delay with the review.

I only have two requests for you because otherwise this looks great:

  • It is better to use String instead of TokenStream as the latter leaks proc_macro2 into our public API, meaning that we would have to do releases from time to time just to keep up to date with proc_macro2.
  • There should be a test for the CLI args and also some documentation explaining the syntax of the attributes as right now.

Edit: I also have an additional question for you that is non-blocking and can be addressed later (even by someone else). Would it be possible to re-implement the custom derives functionality using the custom attributes machinery instead?

@mkroening
Copy link
Copy Markdown
Contributor Author

Thanks for the review!

  • It is better to use String instead of TokenStream as the latter leaks proc_macro2 into our public API, meaning that we would have to do releases from time to time just to keep up to date with proc_macro2.

  • There should be a test for the CLI args

and also some documentation explaining the syntax of the attributes as right now.

Where would I put that? I did not find anything similar for --with-derive-custom.

Would it be possible to re-implement the custom derives functionality using the custom attributes machinery instead?

That should be possible! Would you like me to tackle this in this PR or in a separate one?

I have also implemented support for annotations, but error reporting is difficult there. It currently panics, if the attribute is not parsable as TokenStream.

@pvdrz
Copy link
Copy Markdown
Contributor

pvdrz commented Aug 29, 2024

and also some documentation explaining the syntax of the attributes as right now.

Where would I put that? I did not find anything similar for --with-derive-custom.

This would go in bindgen-cli as part of the docstring for the respective fields so clap can generate the --help message with that documentation. This is how it looks for the --with-derive-custom.* flags:

$ bindgen --help
Generates Rust bindings from C/C++ headers.

Usage: bindgen <FLAGS> <OPTIONS> <HEADER> -- <CLANG_ARGS>...

Arguments:
  [HEADER]         C or C++ header file
  [CLANG_ARGS]...  Arguments to be passed straight through to clang

Options:
      ...
      --with-derive-custom <CUSTOM>
          Derive custom traits on any kind of type. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros
      --with-derive-custom-struct <CUSTOM>
          Derive custom traits on a `struct`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros
      --with-derive-custom-enum <CUSTOM>
          Derive custom traits on an `enum. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros
      --with-derive-custom-union <CUSTOM>
          Derive custom traits on a `union`. The CUSTOM value must be of the shape REGEX=DERIVE where DERIVE is a coma-separated list of derive macros

Would it be possible to re-implement the custom derives functionality using the custom attributes machinery instead?

That should be possible! Would you like me to tackle this in this PR or in a separate one?

I'd do it on a separate one so it is easier to review and track.

Thanks!

@mkroening
Copy link
Copy Markdown
Contributor Author

This would go in bindgen-cli as part of the docstring for the respective fields so clap can generate the --help message with that documentation. This is how it looks for the --with-derive-custom.* flags:

Ah, that's what you mean. I wondered, since I had already done that when opening this PR. Perhaps you overlooked it?

I have also fixed the formatting for CI.

@pvdrz
Copy link
Copy Markdown
Contributor

pvdrz commented Aug 30, 2024

Oh my bad, it seems my head just skipped that section of code 🤣. It seems there are some compilation errors due to the change from TokenStream to String, could you fix those so we can roll this up?. Thanks!

@mkroening mkroening force-pushed the attributes branch 4 times, most recently from fd1409c to 8881246 Compare August 31, 2024 11:16
Signed-off-by: Martin Kröning <martin.kroening@eonerc.rwth-aachen.de>
@mkroening
Copy link
Copy Markdown
Contributor Author

The CI is green now. :)

@pvdrz pvdrz added this pull request to the merge queue Sep 3, 2024
Merged via the queue into rust-lang:main with commit 9a8e5ca Sep 3, 2024
@mkroening mkroening deleted the attributes branch September 3, 2024 14:45
thedataking added a commit to immunant/rust-bindgen that referenced this pull request Aug 8, 2025
s/coma/comma/ in the strings added by PR rust-lang#2866.

Signed-off-by: Per Larsen <perlarsen@google.com>
github-merge-queue bot pushed a commit that referenced this pull request Aug 8, 2025
s/coma/comma/ in the strings added by PR #2866.

Signed-off-by: Per Larsen <perlarsen@google.com>
ojeda pushed a commit to ojeda/linux that referenced this pull request Mar 31, 2026
By default bindgen will convert 'enum lru_status' into a typedef for an
integer. For the most part, an integer of the same size as the enum
results in the correct ABI, but in the specific case of CFI, that is not
the case. The CFI encoding is supposed to be the same as a struct called
'lru_status' rather than the name of the underlying native integer type.

To fix this, tell bindgen to generate a newtype and set the CFI type
explicitly. Note that we need to set the CFI attribute explicitly as
bindgen is using repr(transparent), which is otherwise identical to the
inner type for ABI purposes.

This allows us to remove the page range helper C function in Binder
without risking a CFI failure when list_lru_walk calls the provided
function pointer.

The --with-attribute-custom-enum argument requires bindgen v0.71 or
greater.

[ In particular, the feature was added in 0.71.0 [1][2].

  In addition, `feature(cfi_encoding)` has been available since
  Rust 1.71.0 [3].

  Link: rust-lang/rust-bindgen#2520 [1]
  Link: rust-lang/rust-bindgen#2866 [2]
  Link: rust-lang/rust#105452 [3]

    - Miguel ]

My testing procedure was to add this to the android17-6.18 branch and
verify that rust_shrink_free_page is successfully called without crash,
and verify that it does in fact crash when the cfi_encoding is set to
other values. Note that I couldn't test this on android16-6.12 as that
branch uses a bindgen version that is too old.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260223-cfi-lru-status-v2-1-89c6448a63a4@google.com
[ Rebased on top of the minimum Rust version bump series which provide
  the required `bindgen` version. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
ojeda pushed a commit to ojeda/linux that referenced this pull request Apr 1, 2026
By default bindgen will convert 'enum lru_status' into a typedef for an
integer. For the most part, an integer of the same size as the enum
results in the correct ABI, but in the specific case of CFI, that is not
the case. The CFI encoding is supposed to be the same as a struct called
'lru_status' rather than the name of the underlying native integer type.

To fix this, tell bindgen to generate a newtype and set the CFI type
explicitly. Note that we need to set the CFI attribute explicitly as
bindgen is using repr(transparent), which is otherwise identical to the
inner type for ABI purposes.

This allows us to remove the page range helper C function in Binder
without risking a CFI failure when list_lru_walk calls the provided
function pointer.

The --with-attribute-custom-enum argument requires bindgen v0.71 or
greater.

[ In particular, the feature was added in 0.71.0 [1][2].

  In addition, `feature(cfi_encoding)` has been available since
  Rust 1.71.0 [3].

  Link: rust-lang/rust-bindgen#2520 [1]
  Link: rust-lang/rust-bindgen#2866 [2]
  Link: rust-lang/rust#105452 [3]

    - Miguel ]

My testing procedure was to add this to the android17-6.18 branch and
verify that rust_shrink_free_page is successfully called without crash,
and verify that it does in fact crash when the cfi_encoding is set to
other values. Note that I couldn't test this on android16-6.12 as that
branch uses a bindgen version that is too old.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260223-cfi-lru-status-v2-1-89c6448a63a4@google.com
[ Rebased on top of the minimum Rust version bump series which provide
  the required `bindgen` version. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Darksonn added a commit to Darksonn/linux that referenced this pull request Apr 1, 2026
By default bindgen will convert 'enum lru_status' into a typedef for an
integer. For the most part, an integer of the same size as the enum
results in the correct ABI, but in the specific case of CFI, that is not
the case. The CFI encoding is supposed to be the same as a struct called
'lru_status' rather than the name of the underlying native integer type.

To fix this, tell bindgen to generate a newtype and set the CFI type
explicitly. Note that we need to set the CFI attribute explicitly as
bindgen is using repr(transparent), which is otherwise identical to the
inner type for ABI purposes.

This allows us to remove the page range helper C function in Binder
without risking a CFI failure when list_lru_walk calls the provided
function pointer.

The --with-attribute-custom-enum argument requires bindgen v0.71 or
greater.

[ In particular, the feature was added in 0.71.0 [1][2].

  In addition, `feature(cfi_encoding)` has been available since
  Rust 1.71.0 [3].

  Link: rust-lang/rust-bindgen#2520 [1]
  Link: rust-lang/rust-bindgen#2866 [2]
  Link: rust-lang/rust#105452 [3]

    - Miguel ]

My testing procedure was to add this to the android17-6.18 branch and
verify that rust_shrink_free_page is successfully called without crash,
and verify that it does in fact crash when the cfi_encoding is set to
other values. Note that I couldn't test this on android16-6.12 as that
branch uses a bindgen version that is too old.

[ Rebased on top of the minimum Rust version bump series which provide
  the required `bindgen` version. - Miguel ]

Link: https://patch.msgid.link/20260223-cfi-lru-status-v2-1-89c6448a63a4@google.com
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20260401114540.30108-32-ojeda@kernel.org
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
ojeda pushed a commit to Rust-for-Linux/linux that referenced this pull request Apr 6, 2026
By default bindgen will convert 'enum lru_status' into a typedef for an
integer. For the most part, an integer of the same size as the enum
results in the correct ABI, but in the specific case of CFI, that is not
the case. The CFI encoding is supposed to be the same as a struct called
'lru_status' rather than the name of the underlying native integer type.

To fix this, tell bindgen to generate a newtype and set the CFI type
explicitly. Note that we need to set the CFI attribute explicitly as
bindgen is using repr(transparent), which is otherwise identical to the
inner type for ABI purposes.

This allows us to remove the page range helper C function in Binder
without risking a CFI failure when list_lru_walk calls the provided
function pointer.

The --with-attribute-custom-enum argument requires bindgen v0.71 or
greater.

[ In particular, the feature was added in 0.71.0 [1][2].

  In addition, `feature(cfi_encoding)` has been available since
  Rust 1.71.0 [3].

  Link: rust-lang/rust-bindgen#2520 [1]
  Link: rust-lang/rust-bindgen#2866 [2]
  Link: rust-lang/rust#105452 [3]

    - Miguel ]

My testing procedure was to add this to the android17-6.18 branch and
verify that rust_shrink_free_page is successfully called without crash,
and verify that it does in fact crash when the cfi_encoding is set to
other values. Note that I couldn't test this on android16-6.12 as that
branch uses a bindgen version that is too old.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260223-cfi-lru-status-v2-1-89c6448a63a4@google.com
[ Rebased on top of the minimum Rust version bump series which provide
  the required `bindgen` version. - Miguel ]
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260405235309.418950-32-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
ojeda pushed a commit to Rust-for-Linux/linux that referenced this pull request Apr 7, 2026
By default bindgen will convert 'enum lru_status' into a typedef for an
integer. For the most part, an integer of the same size as the enum
results in the correct ABI, but in the specific case of CFI, that is not
the case. The CFI encoding is supposed to be the same as a struct called
'lru_status' rather than the name of the underlying native integer type.

To fix this, tell bindgen to generate a newtype and set the CFI type
explicitly. Note that we need to set the CFI attribute explicitly as
bindgen is using repr(transparent), which is otherwise identical to the
inner type for ABI purposes.

This allows us to remove the page range helper C function in Binder
without risking a CFI failure when list_lru_walk calls the provided
function pointer.

The --with-attribute-custom-enum argument requires bindgen v0.71 or
greater.

[ In particular, the feature was added in 0.71.0 [1][2].

  In addition, `feature(cfi_encoding)` has been available since
  Rust 1.71.0 [3].

  Link: rust-lang/rust-bindgen#2520 [1]
  Link: rust-lang/rust-bindgen#2866 [2]
  Link: rust-lang/rust#105452 [3]

    - Miguel ]

My testing procedure was to add this to the android17-6.18 branch and
verify that rust_shrink_free_page is successfully called without crash,
and verify that it does in fact crash when the cfi_encoding is set to
other values. Note that I couldn't test this on android16-6.12 as that
branch uses a bindgen version that is too old.

Signed-off-by: Alice Ryhl <aliceryhl@google.com>
Link: https://patch.msgid.link/20260223-cfi-lru-status-v2-1-89c6448a63a4@google.com
[ Rebased on top of the minimum Rust version bump series which provide
  the required `bindgen` version. - Miguel ]
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260405235309.418950-32-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support conditional derives / custom attributes

2 participants