Input C/C++ Header
int api(int x);
__asm__(".symver api,api@VERS_1");
The shared object that implements api exports two versions (this is not the bindgen input):
int api_v1(int x) { return 101; }
int api_v2(int x) { return 202; }
__asm__(".symver api_v1,api@VERS_1");
__asm__(".symver api_v2,api@@VERS_2");
VERS_1 { global: api; local: *; };
VERS_2 { global: api; } VERS_1;
Bindgen Invocation
$ clang -O0 -fPIC -shared -o libapi.so lib.c -Wl,--version-script=vers.map
$ bindgen input.h --rust-target 1.77 --no-rustfmt-bindings -o bindings.rs
Actual Results
A C TU that includes the header compiles a relocation to the non-default version api@VERS_1. bindgen emits an unversioned api:
extern "C" {
pub fn api(x: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
}
On the same libapi.so (nm shows api@VERS_1 and default api@@VERS_2):
C caller including input.h: v=101
Rust caller using bindings.rs: v=202
Control: the same shared object, but a header that is only int api(int x); (no .symver). Then both C and Rust print v=202.
bindgen 0.70.1, 0.73.1, and current main (77cbc723) all emit the unversioned pub fn api. There is no symver handling in the bindgen sources.
Declaration-level __asm__("other_name") and #pragma redefine_extname already become #[link_name]. File-scope .symver does not.
This is ELF-only (GNU symbol versioning). Layout tests are not involved.
Expected Results
The generated binding should call the same symbol a C TU that includes the header calls, for example by emitting a versioned link_name for api@VERS_1, or by diagnosing that the header selects a non-default version.
Silently emitting an unversioned api makes a Rust caller bind the default api@@VERS_2 while C callers of that header use api@VERS_1.
Environment
bindgen current main: 77cbc723
bindgen crate: 0.70.1
clang: Ubuntu clang 15.0.7
rustc: 1.86.0
target: x86_64-unknown-linux-gnu
Input C/C++ Header
The shared object that implements
apiexports two versions (this is not the bindgen input):Bindgen Invocation
Actual Results
A C TU that includes the header compiles a relocation to the non-default version
api@VERS_1. bindgen emits an unversionedapi:On the same
libapi.so(nmshowsapi@VERS_1and defaultapi@@VERS_2):Control: the same shared object, but a header that is only
int api(int x);(no.symver). Then both C and Rust printv=202.bindgen 0.70.1, 0.73.1, and current main (
77cbc723) all emit the unversionedpub fn api. There is nosymverhandling in the bindgen sources.Declaration-level
__asm__("other_name")and#pragma redefine_extnamealready become#[link_name]. File-scope.symverdoes not.This is ELF-only (GNU symbol versioning). Layout tests are not involved.
Expected Results
The generated binding should call the same symbol a C TU that includes the header calls, for example by emitting a versioned
link_nameforapi@VERS_1, or by diagnosing that the header selects a non-default version.Silently emitting an unversioned
apimakes a Rust caller bind the defaultapi@@VERS_2while C callers of that header useapi@VERS_1.Environment