Skip to content

Commit

Permalink
Let LLVM mangle the link name of static wrappers (#2448)
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdrz committed Mar 17, 2023
1 parent b3239c5 commit a101063
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 28 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -169,6 +169,9 @@
* The source file generated when the `--wrap-static-fns` flag is enabled now
contains `#include` directives with all the input headers and all the source
code added with the `header_contents` method.
* The source file generated when the `--wrap-static-fns` flag no longer uses
`asm` labeling and the link name of static wrapper functions is allowed to
be mangled.
## Removed
* The following deprecated flags were removed: `--use-msvc-mangling`,
`--rustfmt-bindings` and `--size_t-is-usize`.
Expand Down
Expand Up @@ -2,19 +2,11 @@

// Static wrappers

int foo__extern(void) asm("foo__extern");
int foo__extern(void) { return foo(); }
int bar__extern(void) asm("bar__extern");
int bar__extern(void) { return bar(); }
int takes_ptr__extern(int *arg) asm("takes_ptr__extern");
int takes_ptr__extern(int *arg) { return takes_ptr(arg); }
int takes_fn_ptr__extern(int (*f) (int)) asm("takes_fn_ptr__extern");
int takes_fn_ptr__extern(int (*f) (int)) { return takes_fn_ptr(f); }
int takes_fn__extern(int (f) (int)) asm("takes_fn__extern");
int takes_fn__extern(int (f) (int)) { return takes_fn(f); }
int takes_alias__extern(func f) asm("takes_alias__extern");
int takes_alias__extern(func f) { return takes_alias(f); }
int takes_qualified__extern(const int *const *arg) asm("takes_qualified__extern");
int takes_qualified__extern(const int *const *arg) { return takes_qualified(arg); }
enum foo takes_enum__extern(const enum foo f) asm("takes_enum__extern");
enum foo takes_enum__extern(const enum foo f) { return takes_enum(f); }
16 changes: 8 additions & 8 deletions bindgen-tests/tests/expectations/tests/wrap-static-fns.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 8 additions & 3 deletions bindgen/codegen/helpers.rs
Expand Up @@ -7,7 +7,7 @@ use quote::TokenStreamExt;

pub(crate) mod attributes {
use proc_macro2::{Ident, Span, TokenStream};
use std::str::FromStr;
use std::{borrow::Cow, str::FromStr};

pub(crate) fn repr(which: &str) -> TokenStream {
let which = Ident::new(which, Span::call_site());
Expand Down Expand Up @@ -62,10 +62,15 @@ pub(crate) mod attributes {
}
}

pub(crate) fn link_name(name: &str) -> TokenStream {
pub(crate) fn link_name<const MANGLE: bool>(name: &str) -> TokenStream {
// LLVM mangles the name by default but it's already mangled.
// Prefixing the name with \u{1} should tell LLVM to not mangle it.
let name = format!("\u{1}{}", name);
let name: Cow<'_, str> = if MANGLE {
name.into()
} else {
format!("\u{1}{}", name).into()
};

quote! {
#[link_name = #name]
}
Expand Down
6 changes: 3 additions & 3 deletions bindgen/codegen/mod.rs
Expand Up @@ -751,7 +751,7 @@ impl CodeGenerator for Var {
link_name,
None,
) {
attrs.push(attributes::link_name(link_name));
attrs.push(attributes::link_name::<false>(link_name));
}

let maybe_mut = if self.is_const() {
Expand Down Expand Up @@ -4155,7 +4155,7 @@ impl CodeGenerator for Function {
Some(abi),
)
{
attributes.push(attributes::link_name(link_name));
attributes.push(attributes::link_name::<false>(link_name));
has_link_name_attr = true;
}

Expand All @@ -4169,7 +4169,7 @@ impl CodeGenerator for Function {

if is_internal && ctx.options().wrap_static_fns && !has_link_name_attr {
let name = canonical_name.clone() + ctx.wrap_static_fns_suffix();
attributes.push(attributes::link_name(&name));
attributes.push(attributes::link_name::<true>(&name));
}

let ident = ctx.rust_ident(canonical_name);
Expand Down
6 changes: 0 additions & 6 deletions bindgen/codegen/serialize.rs
Expand Up @@ -105,12 +105,6 @@ impl<'a> CSerialize<'a> for Function {
// The function's return type
let ret_ty = signature.return_type();

// Write `ret_ty wrap_name(args) asm("wrap_name");`
ret_ty.serialize(ctx, (), stack, writer)?;
write!(writer, " {}(", wrap_name)?;
serialize_args(&args, ctx, writer)?;
writeln!(writer, ") asm(\"{}\");", wrap_name)?;

// Write `ret_ty wrap_name(args) { return name(arg_names)' }`
ret_ty.serialize(ctx, (), stack, writer)?;
write!(writer, " {}(", wrap_name)?;
Expand Down

0 comments on commit a101063

Please sign in to comment.