Skip to content

Commit 594eb7b

Browse files
Add support for the "efiapi" ABI. (#2481)
This allows for use of `extern "efiapi" ...` which is now stable since the following commit: `https://github.com/rust-lang/rust/commit/46f9e878f68e6ece9e8dad54c67e97e5dd5838e1`
1 parent dcc21c1 commit 594eb7b

File tree

6 files changed

+52
-7
lines changed

6 files changed

+52
-7
lines changed

bindgen-cli/options.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ struct BindgenCommand {
336336
/// Deduplicates extern blocks.
337337
#[arg(long)]
338338
merge_extern_blocks: bool,
339-
/// Overrides the ABI of functions matching <regex>. The <OVERRIDE> value must be of the shape <REGEX>=<ABI> where <ABI> can be one of C, stdcall, fastcall, thiscall, aapcs, win64 or C-unwind.
339+
/// Overrides the ABI of functions matching <regex>. The <OVERRIDE> value must be of the shape <REGEX>=<ABI> where <ABI> can be one of C, stdcall, efiapi, fastcall, thiscall, aapcs, win64 or C-unwind.
340340
#[arg(long, value_name = "OVERRIDE")]
341341
override_abi: Vec<String>,
342342
/// Wrap unsafe operations in unsafe blocks.

bindgen-tests/tests/expectations/tests/abi-override.rs

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
// bindgen-flags: --override-abi=foo=fastcall --override-abi=bar=stdcall
1+
// bindgen-flags: --override-abi=foo=fastcall --override-abi=bar=stdcall --override-abi=boo=efiapi --override-abi=foobar=efiapi
22

33
void foo();
44
void bar();
55
void baz();
6+
7+
typedef void (*boo)();
8+
typedef void (*foobar)(boo boo);

bindgen/codegen/mod.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,6 +2566,9 @@ impl Method {
25662566
ClangAbi::Known(Abi::CUnwind) => {
25672567
ctx.options().rust_features().c_unwind_abi
25682568
}
2569+
ClangAbi::Known(Abi::EfiApi) => {
2570+
ctx.options().rust_features().abi_efiapi
2571+
}
25692572
_ => true,
25702573
};
25712574

@@ -4089,9 +4092,8 @@ impl TryToRustTy for FunctionSig {
40894092
// TODO: we might want to consider ignoring the reference return value.
40904093
let ret = utils::fnsig_return_ty(ctx, self);
40914094
let arguments = utils::fnsig_arguments(ctx, self);
4092-
let abi = self.abi(ctx, None);
40934095

4094-
match abi {
4096+
match self.abi(ctx, None) {
40954097
ClangAbi::Known(Abi::ThisCall)
40964098
if !ctx.options().rust_features().thiscall_abi =>
40974099
{
@@ -4110,7 +4112,13 @@ impl TryToRustTy for FunctionSig {
41104112
warn!("Skipping function with C-unwind ABI that isn't supported by the configured Rust target");
41114113
Ok(proc_macro2::TokenStream::new())
41124114
}
4113-
_ => Ok(quote! {
4115+
ClangAbi::Known(Abi::EfiApi)
4116+
if !ctx.options().rust_features().abi_efiapi =>
4117+
{
4118+
warn!("Skipping function with efiapi ABI that isn't supported by the configured Rust target");
4119+
Ok(proc_macro2::TokenStream::new())
4120+
}
4121+
abi => Ok(quote! {
41144122
unsafe extern #abi fn ( #( #arguments ),* ) #ret
41154123
}),
41164124
}
@@ -4243,6 +4251,17 @@ impl CodeGenerator for Function {
42434251
);
42444252
return None;
42454253
}
4254+
ClangAbi::Known(Abi::EfiApi)
4255+
if !ctx.options().rust_features().abi_efiapi =>
4256+
{
4257+
unsupported_abi_diagnostic::<true>(
4258+
name,
4259+
item.location(),
4260+
"efiapi",
4261+
ctx,
4262+
);
4263+
return None;
4264+
}
42464265
ClangAbi::Known(Abi::Win64) if signature.is_variadic() => {
42474266
unsupported_abi_diagnostic::<true>(
42484267
name,

bindgen/features.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ macro_rules! rust_target_base {
131131
/// Rust stable 1.64
132132
/// * `core_ffi_c` ([Tracking issue](https://github.com/rust-lang/rust/issues/94501))
133133
=> Stable_1_64 => 1.64;
134+
/// Rust stable 1.68
135+
/// * `abi_efiapi` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/65815))
136+
=> Stable_1_68 => 1.68;
134137
/// Nightly rust
135138
/// * `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202))
136139
/// * `vectorcall` calling convention (no tracking issue)
@@ -144,7 +147,7 @@ rust_target_base!(rust_target_def);
144147
rust_target_base!(rust_target_values_def);
145148

146149
/// Latest stable release of Rust
147-
pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_64;
150+
pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_68;
148151

149152
/// Create RustFeatures struct definition, new(), and a getter for each field
150153
macro_rules! rust_feature_def {
@@ -241,6 +244,9 @@ rust_feature_def!(
241244
Stable_1_64 {
242245
=> core_ffi_c;
243246
}
247+
Stable_1_68 {
248+
=> abi_efiapi;
249+
}
244250
Nightly {
245251
=> thiscall_abi;
246252
=> vectorcall_abi;

bindgen/ir/function.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ pub enum Abi {
176176
C,
177177
/// The "stdcall" ABI.
178178
Stdcall,
179+
/// The "efiapi" ABI.
180+
EfiApi,
179181
/// The "fastcall" ABI.
180182
Fastcall,
181183
/// The "thiscall" ABI.
@@ -197,6 +199,7 @@ impl FromStr for Abi {
197199
match s {
198200
"C" => Ok(Self::C),
199201
"stdcall" => Ok(Self::Stdcall),
202+
"efiapi" => Ok(Self::EfiApi),
200203
"fastcall" => Ok(Self::Fastcall),
201204
"thiscall" => Ok(Self::ThisCall),
202205
"vectorcall" => Ok(Self::Vectorcall),
@@ -213,6 +216,7 @@ impl std::fmt::Display for Abi {
213216
let s = match *self {
214217
Self::C => "C",
215218
Self::Stdcall => "stdcall",
219+
Self::EfiApi => "efiapi",
216220
Self::Fastcall => "fastcall",
217221
Self::ThisCall => "thiscall",
218222
Self::Vectorcall => "vectorcall",
@@ -263,6 +267,9 @@ impl quote::ToTokens for ClangAbi {
263267
/// A function signature.
264268
#[derive(Debug)]
265269
pub(crate) struct FunctionSig {
270+
/// The name of this function signature.
271+
name: String,
272+
266273
/// The return type of the function.
267274
return_type: TypeId,
268275

@@ -572,7 +579,8 @@ impl FunctionSig {
572579
warn!("Unknown calling convention: {:?}", call_conv);
573580
}
574581

575-
Ok(FunctionSig {
582+
Ok(Self {
583+
name: spelling,
576584
return_type: ret,
577585
argument_types: args,
578586
is_variadic: ty.is_variadic(),
@@ -611,6 +619,13 @@ impl FunctionSig {
611619
} else {
612620
self.abi
613621
}
622+
} else if let Some((abi, _)) = ctx
623+
.options()
624+
.abi_overrides
625+
.iter()
626+
.find(|(_, regex_set)| regex_set.matches(&self.name))
627+
{
628+
ClangAbi::Known(*abi)
614629
} else {
615630
self.abi
616631
}

0 commit comments

Comments
 (0)