実装が C を使用しているかどうかによって異なります 低レベルのユーティリティのインターフェースかどうか
言語実装が C を介さずにシステムコールに直接アクセスできる場合 VDSO を使用する必要のないラッパー (たとえば、適切な SYSENTER
を生成できます) syscall を実行するための機械語命令)、しかし、VDSO を使用することを決定して、それを利用することができます。その場合、言語はすべての ABI 規則に従う必要さえなく、カーネルの規則だけに従う必要があります。 (たとえば、ABI が提供する呼び出し元安全な呼び出し元安全なレジスタの区別は必要なく、スタックの使用を避けることもできます)。
libc.so
すら使わない言語実装例 ボーンズスキームです。他にもいくつかあります。
VDSO についての私の理解では、VDSO はカーネルによって提供される抽象化であり、さまざまな x86 プロセッサ ファミリ間で syscall を実装する際のさまざまな小さな違い (ユーザーランド -> カーネル遷移に関連) を抽象化するものです。特定のプロセッサ ターゲットを選択した場合、VDSO は必要なく、いつでも回避できます。
私の知る限り、VDSO は ELF 共有オブジェクトであり、(最近コンパイルされた 3.8.3 カーネルを搭載した私の Debian/AMD64 上で) セグメント ffffffffff600000-ffffffffff601000
にあります。; cat /proc/self/maps
で正確にチェックしてください どこですか)。そのため、ELF 共有オブジェクトの編成を理解し、そこからシンボルを取得する必要があります。これとそのリンクを参照してください。 VDSO は、x86-64 ABI 仕様に記載されている呼び出しに C 規則を使用します。
ELF は十分に文書化された形式です。また、x86-64 ABI 規則 (C 呼び出し規則を正確に定義し、プロセスのイメージがどのように開始されるかを正確に定義します。execve(2) も参照してください) のマニュアル ページと、もちろんカーネルのドキュメントなので、私にはわかりません。あなたの問題は何ですか。 ELF を理解するには時間がかかることに同意します (10 年前に理解しましたが、記憶が曖昧です)。 <elf.h>
も読んでください
例えば;実行中 (zsh
の下) 64 ビット Debian x86-64 上)
% file $(which sash)
/bin/sash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
statically linked, for GNU/Linux 2.6.26,
BuildID[sha1]=0x0347fcc08fba2f811f58af99f26111d0f579a9f6, stripped
% ldd $(which sash)
not a dynamic executable
% sash
Stand-alone shell (version 3.7)
> ps |grep sash
21635 pts/3 00:00:00 sash
> cat /proc/21635/maps
00400000-004da000 r-xp 00000000 08:01 4985590 /bin/sash
006da000-006dc000 rw-p 000da000 08:01 4985590 /bin/sash
006dc000-006e1000 rw-p 00000000 00:00 0
017e3000-01806000 rw-p 00000000 00:00 0 [heap]
7fe4950e5000-7fe4950e7000 rw-p 00000000 00:00 0
7fff3f130000-7fff3f151000 rw-p 00000000 00:00 0 [stack]
7fff3f173000-7fff3f175000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
こちらの回答もご覧ください。
おそらく、VDSO を単純に解析できる動的リンカーの最小限のバージョンがランタイム内に必要になるでしょう。プロセスが開始される正確な状態、特に auxv
の役割を理解したいと思うことは間違いありません。 、補助ベクトル (これらの詳細は本当に忘れていますが、重要であることは覚えています)。例を参照してください。この記事
実際、ランタイムを確実に開始することは、おそらく VDSO の問題よりも困難です。
また、いくつかのことを説明している Linux アセンブリのハウツーを読むこともできます (ただし、x86-64 よりも x86 についての詳細です)
ところで、http://musl-libc.org/ (代替の libc) のコードは、はるかに読みやすく理解しやすいです (動的リンクや pthreads などを行う方法を簡単に学習できます)。
Linux カーネル ツリーの次のファイルが役に立ちました:
Documentation/ABI/stable/vdso
(vDSO オブジェクトとは何ですか?)Documentation/vDSO/parse_vdso.c
(vDSO オブジェクトのリファレンス パーサー)
vDSO オブジェクトは、Linux では常に amd64 プロセスのアドレス空間にマップされる仮想動的共有オブジェクトです。クイック システム コールの実装に使用できます。 vDSO オブジェクト内の関数にアクセスするには、
- オブジェクトを見つける
- シンボル テーブルからアドレスを抽出する
どちらも、CC0 ライセンスの参照実装 parse_vdso.c で実行できます。