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

オープン
#3,460 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
c, linux, rust

調査の方向性

まず input.h、lib.c、vers.map の再現から始め、次に bindgen による宣言レベルの asm とファイルスコープの .symver の扱いを追跡します。issue では、ソースに symver の扱いが存在しないことが指摘されています。完了条件は、bindings が api@VERS_1 を保持するか、サポートされていないバージョニングを診断し、C と Rust の呼び出し側が異なるシンボルを選択しなくなることです。

索引モデルが issue の本文から書いたものです。

説明

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
主要言語
Rust
スター
5.3k
フォーク
846
平均マージ
2日 6時間
マージ済み PR(30日)
11

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

rust-lang/rust-bindgen のほかの issue

rust-lang/rust-bindgen の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。