Manpages

名 前

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/ に 書 か れ て い る 。