名 前
vDSO − 仮 想 ELF 動 的 共 有 オ ブ ジ ェ ク ト の 概 要
書 式
#include <sys/auxv.h>
void *vdso = (uintptr_t) getauxval(AT_SYSINFO_EHDR);
説 明
"vDSO" (virtual dynamic shared object; 仮 想 動 的 共 有 オ ブ ジ ェ ク ト ) は 、 カ ー ネ ル が 自 動 的 に す べ て の ユ ー ザ ー 空 間 ア プ リ ケ ー シ ョ ン の ア ド レ ス 空 間 に マ ッ ピ ン グ を 行 う 小 さ な 共 有 ラ イ ブ ラ リ で あ る 。 vDSO は ほ と ん ど の 場 合 C ラ イ ブ ラ リ か ら 呼 び 出 さ れ る た め 、 ア プ リ ケ ー シ ョ ン は 通 常 こ れ ら の 詳 細 を 自 分 で は 気 に す る 必 要 は な い 。 こ の よ う に 、 標 準 関 数 と C ラ イ ブ ラ リ を 使 っ て 通 常 の 方 法 で コ ー ド を 作 成 す る こ と で 、 vDSO 経 由 で 利 用 可 能 な 機 能 が 活 用 さ れ る こ と に な る 。 い っ た い な ぜ vDSO は 存 在 し て い る の か ? カ ー ネ ル が 提 供 す る シ ス テ ム コ ー ル の い く つ か は 、 ユ ー ザ ー 空 間 の コ ー ド が こ れ ら の シ ス テ ム コ ー ル を 頻 繁 に 呼 び 出 す こ と に な り 、 こ の よ う な 呼 び 出 し が 全 体 の 性 能 を 支 配 す る よ う に な る 場 合 が あ る 。 こ れ は 、 呼 び 出 し の 頻 度 と 、 ユ ー ザ ー 空 間 か ら 抜 け て カ ー ネ ル に 入 る こ と に よ る コ ン テ キ ス ト ス イ ッ チ の オ ー バ ー ヘ ッ ド の 両 方 に 起 因 す る 。 こ の 文 書 の 残 り の 部 分 は 、 一 般 の 開 発 者 向 け と い う で は な く 、 好 奇 心 が あ る 人 と C ラ イ ブ ラ リ の 開 発 者 向 け の 内 容 と な っ て い る 。 も し あ な た が C ラ イ ブ ラ リ で は な く 自 分 の ア プ リ ケ ー シ ョ ン で vDSO を 呼 び だ そ う と し て い る の で あ れ ば 、 ほ と ん ど の 場 合 間 違 っ た こ と を し て い る こ と だ ろ う 。
Example background シ ス テ ム コ ー ル の 呼 び 出 し は 遅 く な る 場 合 が あ る 。 x86 32 ビ ッ ト シ ス テ ム で は 、 シ ス テ ム コ ー ル を 呼 び 出 し た い こ と を カ ー ネ ル に 教 え る た め に ソ フ ト ウ ェ ア 割 り 込 み (int $0x80) を 使 う こ と が で き る 。 し か し な が ら 、 こ の 割 り 込 み は コ ス ト が か か る 処 理 で あ る 。 割 り 込 み が あ る と 、 カ ー ネ ル と プ ロ セ ッ サ ー の マ イ ク ロ コ ー ド の 両 方 の す べ て の 割 り 込 み 処 理 パ ス が 実 行 さ れ る 。 新 し い プ ロ セ ッ サ ー に は 、 シ ス テ ム コ ー ル 呼 び 出 し を 起 動 す る た め の 高 速 な (だ が 、 後 方 互 換 性 が あ る ) 命 令 が 用 意 さ れ て い る 。 C ラ イ ブ ラ リ が 実 行 時 に こ の 機 能 が 利 用 で き る か を 確 認 す る の で は な く 、 C ラ イ ブ ラ リ は vDSO で カ ー ネ ル が 提 供 す る 関 数 を 使 う こ と が で き る 。 用 語 が 紛 ら わ し い 点 に は 注 意 が 必 要 で あ る 。 x86 シ ス テ ム で は 、 シ ス テ ム コ ー ル を 呼 び 出 す 推 奨 さ れ る 方 法 を 判 定 す る の に 使 用 さ れ る vDSO 関 数 は "__kernel_vsyscall" と い う 名 前 だ が 、 x86_64 で は 、 "vsyscall" と い う 用 語 は 、 カ ー ネ ル に 時 刻 は い つ か や 呼 び 出 し 元 は ど の CPU 上 に い る か を 問 い 合 わ せ る た め の 廃 止 予 定 の 方 法 も 参 照 し て い る 。 頻 繁 に 使 用 さ れ る シ ス テ ム コ ー ル の 一 つ が gettimeofday(2) で あ る 。 こ の シ ス テ ム コ ー ル は 、 ユ ー ザ ー 空 間 ア プ リ ケ ー シ ョ ン か ら 直 接 呼 び 出 さ れ る こ と も 、 C ラ イ ブ ラ リ か ら 間 接 的 に 呼 び 出 さ れ る こ と も あ る 。 タ イ ム ス タ ン プ が 必 要 な 場 面 、 タ イ ミ ン グ ル ー プ を 行 う 場 面 、 ポ ー リ ン グ を 行 う 場 面 を 考 え て ほ し い 。 こ れ ら は い ず れ も 現 在 時 刻 が 何 か を 直 ち に 知 り た い の が 普 通 で あ る 。 ま た 、 こ の 情 報 は 秘 密 で は な く 、 (ル ー ト で も 非 特 権 ユ ー ザ ー で も ) 任 意 の 特 権 モ ー ド の 多 く の ア プ リ ケ ー シ ョ ン が 同 じ 情 報 を 取 得 で き る 。 し た が っ て 、 カ ー ネ ル は こ の 質 問 に 応 え る の に 必 要 な 情 報 を プ ロ セ ス が ア ク セ ス で き る メ モ リ ー 上 に 配 置 す る 。 こ れ に よ り 、 gettimeofday(2) は シ ス テ ム コ ー ル か ら 通 常 の 関 数 コ ー ル に な り 、 少 な い メ モ リ ー ア ク セ ス に な る 。
vDSO
を 見 つ け る
vDSO の ベ ー ス ア ド
レ ス は 、 (存 在
す る 場 合 に は )
カ ー ネ ル か ら
各 プ ロ グ ラ ム
に 初 期 補 助 ベ
ク ト ル (getauxval(3) 参
照 ) の AT_SYSINFO_EHDR タ グ
経 由 で 渡 さ れ
る 。
vDSO が
ユ ー ザ ー の メ
モ リ ー マ ッ プ
の 何 か 特 定 の
場 所 に マ ッ ピ
ン グ さ れ る と
仮 定 し て は な
ら な い 。 通 常
新 し い プ ロ セ
ス イ メ ー ジ が
作 成 さ れ る た
び に (execve(2) 実 行
時 点 ) 、 実 行 時
に ベ ー ス ア ド
レ ス の ラ ン ダ
ム 化 が 行 わ れ
る 。 こ れ は
"return−to−libc" 攻 撃
を 防 ぐ た め に
セ キ ュ リ テ ィ
上 の 理 由 か ら
行 わ れ る 。 ア
ー キ テ ク チ ャ
ー に よ っ て は
AT_SYSINFO タ グ も あ
る 。 こ の タ グ
は vsyscall エ ン ト リ
ー ポ イ ン ト の
場 所 を 知 る た
め だ け の も の
で あ り 、 し ば
し ば 省 略 さ れ
る か (利 用 で き
な い 場 合 は ) 0 に
セ ッ ト さ れ る
。 こ の タ グ は
最 初 の vDSO の 実 装
で 使 用 さ れ て
い た も の で あ
り (下 記 の 「 歴
史 」 を 参 照 )、
こ の タ グ を 利
用 す る の は 避
け る べ き で あ
る 。 フ ァ イ ル
フ ォ ー マ ッ ト
vDSO は 完 全 な 形 式
の ELF イ メ ー ジ な
の で 、 vDSO に 対 し
て シ ン ボ ル の
検 索 を 行 う こ
と が で き る 。
こ の た め 、 新
し い カ ー ネ ル
リ リ ー ス で 新
し い シ ン ボ ル
を 追 加 す る こ
と が で き 、 C ラ
イ ブ ラ リ が 別
の バ ー ジ ョ ン
の カ ー ネ ル 上
で 動 作 す る 際
に 実 行 時 に 利
用 可 能 な 機 能
を 検 出 す る こ
と が で き る 。
多 く の 場 合 、 C
ラ イ ブ ラ リ は
最 初 の 呼 び 出
し 時 に 検 出 を
行 い 、 そ れ 以
降 の 呼 び 出 し
で 利 用 で き る
よ う に そ の 結
果 を キ ャ ッ シ
ュ す る 。 す べ
て の シ ン ボ ル
は (GNU の バ ー ジ ョ
ン フ ォ ー マ ッ
ト を 使 っ て ) バ
ー ジ ョ ン が 付
け ら れ て い る
。 こ れ に よ り
、 カ ー ネ ル は
後 方 互 換 性 を
持 た せ つ つ 関
数 の シ グ ネ チ
ャ ー を 更 新 す
る こ と が で き
る 。 つ ま り 、
関 数 が 受 け 取
る 引 き 数 や 返
り 値 が 変 更 さ
れ る こ と が あ
る と い う こ と
で あ る 。 し た
が っ て 、 vDSO の シ
ン ボ ル を 検 索
す る 際 に は 、
自 分 が 期 待 す
る ABI に 一 致 す る
バ ー ジ ョ ン を
し な け れ ば な
ら な い 。 通 常
は vDSO は す べ て の
シ ン ボ ル に
"__vdso_" か "__kernel_" と
い う プ レ フ ィ
ッ ク ス を 付 け
る と い う 慣 習
に 従 っ た 名 前
付 け を 行 っ て
お り 、 他 の 標
準 の シ ン ボ ル
か ら 区 別 す る
こ と が で き る
。 例 え ば 、
"gettimeofday" 関 数 は
""__vdso_gettimeofday" と い
う 名 前 に な っ
て い る 。 こ れ
ら の 関 数 を 呼
び 出 す 場 合 は
標 準 の C の 呼 び
出 し の 慣 習 に
し た が っ て お
け ば よ い 。 特
殊 な レ ジ ス タ
ー や ス タ ッ ク
の 動 作 に 気 を
使 う 必 要 は な
い 。
注 意
ソ ー ス カ ー ネ ル を コ ン パ イ ル す る 際 に 、 vDSO コ ー ド は コ ン パ イ ル さ れ リ ン ク が 行 わ れ る 。 通 常 は ア ー キ テ ク チ ャ ー 固 有 の デ ィ レ ク ト リ に vDSO コ ー ド が 生 成 さ れ る 。
find arch/$ARCH/ −name ’*vdso*.so*’ −o −name ’*gate*.so*’
vDSO
名
vDSO の 名 前 は ア ー
キ テ ク チ ャ ー
に よ り 異 な る
。 こ の 名 前 は glibc
の ldd(1) の 出 力 な
ど に 現 れ る 。
名 前 は コ ー ド
で 必 要 と な る
こ と は な く 、
名 前 を ハ ー ド
コ ー ド し な い
こ と 。
ア ー キ テ ク チ ャ ー 固 有 の 注 意
以 下 の サ ブ 章 で は vDSO の ア ー キ テ ク チ ャ ー 固 有 の 注 意 に つ い て 説 明 す る 。 使 用 さ れ る vDSO は 、 カ ー ネ ル の ABI で は な く 、 ユ ー ザ ー 空 間 コ ー ド の ABI に 基 づ く こ と に 注 意 す る こ と 。 し た が っ て 、 例 え ば 、 i386 32 ビ ッ ト の ELF ラ イ ブ ラ リ 上 で 実 行 す る 場 合 、 i386 32 ビ ッ ト カ ー ネ ル 上 で 実 行 さ れ て い る か x86_64 64 ビ ッ ト カ ー ネ ル 上 で 実 行 さ れ て い る か に 関 わ ら ず 同 じ vDSO が 得 ら れ る 。 し た が っ て 、 以 下 の ど の 節 が 関 係 す る か を 判 断 す る 際 に は ユ ー ザ ー 空 間 ABI の 名 前 を 使 用 す る 必 要 が あ る 。
ARM 関
数
The ARM port has a code page full of utility functions.
Since it’s just a raw page of code, there is no ELF
information for doing symbol lookups or versioning. It does
provide support for different versions though.
For information on this code page, it’s best to refer to the kernel documentation as it’s extremely detailed and covers everything you need to know: Documentation/arm/kernel_user_helpers.txt.
aarch64 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。
bfin
(Blackfin) 関 数
As this CPU lacks a memory management unit (MMU), it
doesn’t set up a vDSO in the normal sense. Instead, it
maps at boot time a few raw functions into a fixed location
in memory. User−space applications then call directly
into that region. There is no provision for backward
compatibility beyond sniffing raw opcodes, but as this is an
embedded CPU, it can get away with things—some of the
object formats it runs aren’t even ELF based
(they’re bFLT/FLAT).
For information
on this code page, it’s best to refer to the public
documentation:
http://docs.blackfin.uclinux.org/doku.php?id=linux−kernel:fixed−code
ia64 (Itanium) 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。
The Itanium port is somewhat tricky. In addition to the vDSO above, it also has "light−weight system calls" (also known as "fast syscalls" or "fsys"). You can invoke these via the __kernel_syscall_via_epc vDSO helper. The system calls listed here have the same semantics as if you called them directly via syscall(2), so refer to the relevant documentation for each. The table below lists the functions available via this mechanism.
parisc
(hppa) 関 数
The parisc port has a code page full of utility functions
called a gateway page. Rather than use the normal ELF
auxiliary vector approach, it passes the address of the page
to the process via the SR2 register. The permissions on the
page are such that merely executing those addresses
automatically executes with kernel privileges and not in
user space. This is done to match the way HP−UX
works.
Since it’s just a raw page of code, there is no ELF information for doing symbol lookups or versioning. Simply call into the appropriate offset via the branch instruction, for example:
ble <offset>(%sr2, %r0)
ppc/32 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。 * の マ ー ク が 付 い た 関 数 は 、 カ ー ネ ル が PowerPC64 (64 ビ ッ ト ) カ ー ネ ル の 場 合 に だ け 利 用 可 能 で あ る 。
ppc/64 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。
s390 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。
s390x 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。
sh (SuperH) 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。
i386 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。
x86_64 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。 こ れ ら の シ ン ボ ル は す べ て "__vdso_" の プ レ フ ィ ッ ク ス な し で も 利 用 で き る が 、 こ れ ら は 無 視 し 、 以 下 の 名 前 だ け を 使 う こ と 。
x86/x32 関 数 以 下 の テ ー ブ ル は vDSO で 公 開 さ れ る シ ン ボ ル の 一 覧 で あ る 。
歴
史
vDSO は 元 々 は 一 つ
の 関 数 vsyscall で あ
っ た 。 古 い カ
ー ネ ル で は 、
プ ロ セ ス の メ
モ リ ー マ ッ プ
に "vdso" で は な
く こ の 名 前 が
見 え る か も し
れ な い 。 時 間
が 経 つ に 連 れ
て 、 こ の 仕 組
み は よ り 多 く
の 機 能 を ユ ー
ザ ー 空 間 に 渡
す 有 効 な 方 法
で あ る と 認 識
さ れ る よ う に
な り 、 現 在 の
形 の vDSO と い う 形
に 見 直 し が 行
わ れ た 。
関 連 項 目
syscalls(2), getauxval(3), proc(5)
Linux の ソ ー ス コ ー ド ツ リ ー の ド キ ュ メ ン ト 、 例 、 ソ ー ス コ ー ド :
Documentation/ABI/stable/vdso
Documentation/ia64/fsys.txt
Documentation/vDSO/* (vDSO の 使 用
例 が あ る )
find arch/ −iname ’*vdso*’ −o −iname ’*gate*’
こ の 文 書 に つ い て
こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。