From ebdf1ce5a217f10a7d3d54c7f0d253c450d37ce7 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Mon, 21 Oct 2024 10:54:31 -0400 Subject: [PATCH 1/3] Wrap libloading::Library::new call in unsafe if --wrap-unsafe-ops --- .../tests/wrap_unsafe_ops_dynamic_loading_simple.rs | 2 +- bindgen/codegen/dyngen.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs index 2f5b4cc5ba..82ed764934 100644 --- a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs @@ -22,7 +22,7 @@ impl TestLib { where P: AsRef<::std::ffi::OsStr>, { - let library = ::libloading::Library::new(path)?; + let library = unsafe { ::libloading::Library::new(path) }?; unsafe { Self::from_library(library) } } pub unsafe fn from_library(library: L) -> Result diff --git a/bindgen/codegen/dyngen.rs b/bindgen/codegen/dyngen.rs index 4b2749ec0c..3109ddf296 100644 --- a/bindgen/codegen/dyngen.rs +++ b/bindgen/codegen/dyngen.rs @@ -83,6 +83,12 @@ impl DynamicItems { let init_fields = &self.init_fields; let struct_implementation = &self.struct_implementation; + let library_new = if ctx.options().wrap_unsafe_ops { + quote!(unsafe { ::libloading::Library::new(path) }) + } else { + quote!(::libloading::Library::new(path)) + }; + let from_library = if ctx.options().wrap_unsafe_ops { quote!(unsafe { Self::from_library(library) }) } else { @@ -100,7 +106,7 @@ impl DynamicItems { path: P ) -> Result where P: AsRef<::std::ffi::OsStr> { - let library = ::libloading::Library::new(path)?; + let library = #library_new?; #from_library } From 51ee9c3964daab84164d1bb699cdd5d6ea715df9 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Mon, 21 Oct 2024 11:00:08 -0400 Subject: [PATCH 2/3] Add test showing bad behavior for non-functions --- .../tests/wrap_unsafe_ops_dynamic_loading_simple.rs | 8 ++++++++ .../headers/wrap_unsafe_ops_dynamic_loading_simple.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs index 82ed764934..d261cc77ec 100644 --- a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs @@ -16,6 +16,7 @@ pub struct TestLib { unsafe extern "C" fn() -> ::std::os::raw::c_int, ::libloading::Error, >, + pub FLUX: Result<*mut ::std::os::raw::c_int, ::libloading::Error>, } impl TestLib { pub unsafe fn new

(path: P) -> Result @@ -33,11 +34,15 @@ impl TestLib { let foo = unsafe { __library.get(b"foo\0") }.map(|sym| *sym); let bar = unsafe { __library.get(b"bar\0") }.map(|sym| *sym); let baz = unsafe { __library.get(b"baz\0") }.map(|sym| *sym); + let FLUX = __library + .get::<*mut ::std::os::raw::c_int>(b"FLUX\0") + .map(|sym| *sym); Ok(TestLib { __library, foo, bar, baz, + FLUX, }) } pub unsafe fn foo( @@ -53,4 +58,7 @@ impl TestLib { pub unsafe fn baz(&self) -> ::std::os::raw::c_int { unsafe { (self.baz.as_ref().expect("Expected function, got error."))() } } + pub unsafe fn FLUX(&self) -> *mut ::std::os::raw::c_int { + *self.FLUX.as_ref().expect("Expected variable, got error.") + } } diff --git a/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h b/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h index 2b8c107185..36a638ae2a 100644 --- a/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h +++ b/bindgen-tests/tests/headers/wrap_unsafe_ops_dynamic_loading_simple.h @@ -3,3 +3,5 @@ int foo(int x, int y); int bar(void *x); int baz(); + +const int FLUX; From 2fa7b49418c90a304b4f933c1c949d2dd298a67b Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Mon, 21 Oct 2024 11:10:16 -0400 Subject: [PATCH 3/3] Wrap __library.get calls for variables if wrap_unsafe_ops --- .../wrap_unsafe_ops_dynamic_loading_simple.rs | 3 +-- bindgen/codegen/dyngen.rs | 22 ++++++++++++------- bindgen/codegen/mod.rs | 1 + 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs index d261cc77ec..05be5d9944 100644 --- a/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs +++ b/bindgen-tests/tests/expectations/tests/wrap_unsafe_ops_dynamic_loading_simple.rs @@ -34,8 +34,7 @@ impl TestLib { let foo = unsafe { __library.get(b"foo\0") }.map(|sym| *sym); let bar = unsafe { __library.get(b"bar\0") }.map(|sym| *sym); let baz = unsafe { __library.get(b"baz\0") }.map(|sym| *sym); - let FLUX = __library - .get::<*mut ::std::os::raw::c_int>(b"FLUX\0") + let FLUX = unsafe { __library.get::<*mut ::std::os::raw::c_int>(b"FLUX\0") } .map(|sym| *sym); Ok(TestLib { __library, diff --git a/bindgen/codegen/dyngen.rs b/bindgen/codegen/dyngen.rs index 3109ddf296..e75e11a297 100644 --- a/bindgen/codegen/dyngen.rs +++ b/bindgen/codegen/dyngen.rs @@ -208,6 +208,7 @@ impl DynamicItems { ident: Ident, ty: TokenStream, is_required: bool, + wrap_unsafe_ops: bool, ) { let member = if is_required { quote! { *mut #ty } @@ -231,15 +232,20 @@ impl DynamicItems { }); let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string()); - self.constructor_inits.push(if is_required { - quote! { - let #ident = __library.get::<*mut #ty>(#ident_str).map(|sym| *sym)?; - } + + let library_get = if wrap_unsafe_ops { + quote!(unsafe { __library.get::<*mut #ty>(#ident_str) }) } else { - quote! { - let #ident = __library.get::<*mut #ty>(#ident_str).map(|sym| *sym); - } - }); + quote!(__library.get::<*mut #ty>(#ident_str)) + }; + + let qmark = if is_required { quote!(?) } else { quote!() }; + + let var_get = quote! { + let #ident = #library_get.map(|sym| *sym)#qmark; + }; + + self.constructor_inits.push(var_get); self.init_fields.push(quote! { #ident diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index c6e3364234..2374ae36d7 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -808,6 +808,7 @@ impl CodeGenerator for Var { .to_rust_ty_or_opaque(ctx, &()) .into_token_stream(), ctx.options().dynamic_link_require_all, + ctx.options().wrap_unsafe_ops, ); } else { result.push(tokens);