LoginSignup
17
9

More than 3 years have passed since last update.

rlibには何が入っている?

Last updated at Posted at 2017-12-09

以下の内容はLinux上で確認しており、ほかのプラットフォームでは異なることが予想されます(規格ベースで調べたかったけど見つからなくて実装ベースで調べてます)

断片的な知識しかないので、以下では作業記録の形で記述します

rlibには何が入っている?

まずは試しにライブラリを作ってみましょう。rustcだけでライブラリを作るサンプルが Rust By Example にあります:

rary.rs
pub fn public_function() {
    println!("called rary's `public_function()`");
}

fn private_function() {
    println!("called rary's `private_function()`");
}

pub fn indirect_access() {
    print!("called rary's `indirect_access()`, that\n> ");

    private_function();
}
rustc --crate-type=lib rary.rs

これでlibrary.rlibが出来上がります(lib{filename}.rlibができる)。これの中身を見てみましょう。これはバイナリファイルなのでxxdで先頭を見てみます

%xxd library.rlib| head -1
00000000: 213c 6172 6368 3e0a 2f20 2020 2020 2020  !<arch>./

この先頭のアスキー文字!<arch>からどうやらこれはarで生成された静的ライブラリであることがわかります。

中身を見てみましょう:

%ar t library.rlib
rary.rary0.rust-cgu.o
rary.rary1.rust-cgu.o
rust.metadata.bin
rary.rary0.rust-cgu.bytecode.encoded
rary.rary1.rust-cgu.bytecode.encoded

アーカイブ自体はar x library.rlibで展開できます。*.oは通常のオブジェクトファイルでnmで中身が見れます

%nm rary.rary0.rust-cgu.o
0000000000000000 d ref.1
0000000000000000 r ref.2
0000000000000000 d ref.4
0000000000000000 d ref.6
0000000000000000 r str.0
0000000000000000 r str.3
0000000000000000 r str.5
                 U _ZN3std2io5stdio6_print17hd8ec97fc8b4f6250E
                 U _ZN4core3fmt9Arguments6new_v117h7bac9064a6920f0fE
0000000000000000 T _ZN4rary15indirect_access17hdfd7893373562372E
0000000000000000 T _ZN4rary15public_function17hf68b81680a0dec22E
0000000000000000 t _ZN4rary16private_function17h70b7e600c8033b10E

名前がマングルされていてわかりにくいですが、rary.rsで定義してある3つの関数と、println!に由来するだろう関数が見えます。

bytecode.*

これもまずxxdで見てみましょう

%xxd rary.rary0.rust-cgu.bytecode.encoded | head -1
00000000: 5255 5354 5f4f 424a 4543 5402 0000 0029  RUST_OBJECT....)

RUST_OBJECTという文字が見えますね。これをもとにググってみるとlibrustc_transのコードにたどり着きます。
どうやらLLVMのバイトコードを埋め込むための形式のようですね。コメントによると以下のような構造になっているようです

//!     RLIB LLVM-BYTECODE OBJECT LAYOUT
//!     Version 2
//!     Bytes    Data
//!     0..10    "RUST_OBJECT" encoded in ASCII
//!     11..14   format version as little-endian u32
//!     15..19   the length of the module identifier string
//!     20..n    the module identifier string
//!     n..n+8   size in bytes of deflate compressed LLVM bitcode as
//!              little-endian u64
//!     n+9..    compressed LLVM bitcode
//!     ?        maybe a byte to make this whole thing even length

このファイルを読み書きするための関数が同じくlibrustc_transで提供されていますが、これはrustc内部のcrateのため、使用するには#[feature(rustc_private)]が必要になります(なのでnightlyでしか使えません)。

rust.metadata.bin

何でしょうねこれ(´・ω・`)
これはxxdで先頭見てもそれっぽい識別用のアスキー文字がないので分からないのですが、内部にGlobalMetaDataのような文字列が見られる事とファイル名から恐らくlibrustc_metadataによって出力されたものと推察されます(名推理)。

目的だったLLVMのバイトコードが手に入ったし、必要なメタデータはcargo-metadataで別途取得できるため、これをこれ以上調べるのはやめました。

最後に

rlibを調べてるのはAccelで使うためのPTXリンカを作るためだったんですが、これでLLVMのバイトコードが依存しているライブラリ毎に生成されることがわかったのでLLVMのコンパイラllcを使って結合したPTX(というかcubin)を生成できそうです。

17
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
9