rust-lang / rust-lang/rust-bindgen

File-scope `.symver` is ignored, so generated bindings call the default symbol version

Open
#3,460 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the input.h, lib.c, and vers.map reproduction, then trace bindgen's handling of declaration-level asm and file-scope .symver; the issue notes that no symver handling exists in the sources. Done means bindings preserve api@VERS_1 or diagnose unsupported versioning, so C and Rust callers no longer select different symbols.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, linux, rust
Domain
compilers, devtools, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.