2015年4月22日 星期三

為什麼 vdso.so.1 是空的?

以下摘錄自 http://codex.wiki/post/135102-931/ :

VDSO就是Virtual Dynamic Shared Object,就是 Kernel 提供的虛擬的.so,這個.so文件不在磁碟上,而是在 Kernel 裡頭。Kernel 把包含某.so的內存頁在程序啟動的時候映射入其內存空間, 對應的程序就可以當普通的.so來使用裡頭的函數。比如syscall()這個函數就是在linux-vdso.so.1裡頭的,但是磁碟上並沒有對應的 文件.可以通過ldd/bin/bash看看。

這樣,隨 kenel 發行的 libc就唯一的和一個特定版本的 kernel 綁定到一起了。注意,VDSO只是隨 kernel 發行,沒有在 kernel 空間運行,這個不會導致 kernel 膨脹。這樣 kernel 和 libc 都不需為能相容多個不同版本而寫太多的代碼,甚至引入太多的bug了。

當然,libc不單單有到 kernel 的介面,還有很多常用的函數,這些函數不需要特別的為不同版本的 kernel 小心編寫,所以,我估計Linux上會出現兩個 libc, 一個 libc在 kernel,只是系統調用的package,另一個 libc還是普通的 libc,只是這個 libc再也不需要花精力去配合如此繁多的kernel了。

姑且一個叫 kernellibc,一個叫 glibc:printf() 這些的還在 glibc。open(),read(),write(),socket()這些卻不再是glibc的了,他們在kernellibc。

Linux 下傳統的系統調用是通過軟中斷(0x80)實現的,在一個Kernel.org的郵件列表中,有一封郵件討論了「"Intel P6 vs P7 system call performance」,最後得出的結論是採用傳統的int 0x80的系統調用浪費了很多時間,而sysenter/sysexit可以彌補這個缺點,所以才最終決定在linux kernel 中用後都替換前者(最終在 2.6版本的 kernel 中才加入了此功能,即採用sysenter/sysexit)。

如何用替換sysenter/sysexit替換以前的 int 0x80呢?linux kenerl 需要考慮到這點:有的機器並不支持sysenter/sysexit,於是它跟glibc說好了,「你以後調用系統調用的時候就從我給你的這個地址調用, 這個地址指向的內容要麼是int 0x80調用方式,要麼是sysenter/sysexit調用方式,我會根據機器來選擇其中一個」(kernel與glibc的配合是如此的默契),這 個地址便是vsyscall的首地址。

可以將vdso看成一個shared objdect file(這個文件實際上不存在),kernel 將其映射到某個地址空間,被所有程序所共享。(我覺得這裡用到了一個技術:多個虛擬頁面映射到同一個物理頁面。即 kernle 把 vdso 映射到某個物理頁面上,然後所有程序都會有一個頁表項指向它,以此來共享,這樣每個程序的vdso地址就可以不相同了)




這個後來常用在 32bit 程式跑在 64 bit  kernel, 或是 64bit 程式跑在32 bit kernel 中...
可使用下列方式查看~
例如:  lmgrd (程式名)
:pts/0)$ ls -l lmgrd
-rwxrwxr-x 1 root root 1509320 Apr 22 10:31 lmgrd
pts/0)$ readelf -h lmgrd
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x4050a0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          1507336 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         8
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 30
pts/0)$ ldd lmgrd
        linux-vdso.so.1 =>  (0x00007fff945d3000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc7888f8000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc7885fc000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc7883e5000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc788026000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc787e22000)
        /lib64/ld-lsb-x86-64.so.3 => /lib64/ld-linux-x86-64.so.2 (0x00007fc788b35000)

有沒有發現, 其中 linux-vdso.so.1 是指到一個未知的函式庫..
這個 linux-vdso.so.1 可是找不到套件可安裝的..  因為它打一開始就不存在 (為虛擬的)


如果, 在執行程式時發生:
"-bash: lmgr no such file or directory" 的情況..  (已確認存在且可執行, 而且用絕對路徑也一樣)
應該就是 linux-vdso.so.1 的對映出問題了,
您可是試著安裝  lsb 或 lsb-core 來解決
apt-get install lsb 或 apt-get install lsb-core

不過要有時會出現相依性問題, 那就得自行去下載相關套件安裝了
http://packages.ubuntu.com/search?suite=default&section=all&arch=any&keywords=lsb-core&searchon=names

以我的小桌機 Ubuntu 12.04 (Linux 3.11.0-24) 來說, 要安裝( dpkg -i *.deb) 以下:
alien_8.86_all.deb
intltool-debian_0.35.0+20060710.1_all.deb
lsb-release_4.0-0ubuntu20_all.deb
debhelper_9.20120115ubuntu3_all.deb
libgettextpo0_0.18.1.1-5ubuntu3_amd64.deb
ncurses-term_5.9-4_all.deb
dh-apparmor_2.7.102-0ubuntu3.10_all.deb
libunistring0_0.9.3-5_amd64.deb
pax_20120216-1_amd64.deb
gettext_0.18.1.1-5ubuntu3_amd64.deb
lsb-base_4.0-0ubuntu20_all.deb
po-debconf_1.0.16+nmu2ubuntu1_all.deb
html2text_1.3.2a-15_amd64.deb
lsb-core_4.0-0ubuntu20_amd64.deb


1 則留言:

  1. Let me tell you something...

    What I'm going to tell you might sound a little weird, maybe even kind of "supernatural"

    BUT what if you could just click "Play" and LISTEN to a short, "musical tone"...

    And INSTANTLY bring MORE MONEY to your life?

    I'm talking about BIG MONEY, even MILLIONS of DOLLARS!!!

    Sounds way too EASY? Think it couldn't possibly be REAL?!?

    Well, Let me tell you the news.

    Sometimes the most significant miracles life has to offer are the easiest to RECEIVE!!!

    Honestly, I'm going to PROVE it to you by allowing you to listen to a real-life "magical money tone" I've synthesized...

    And TOTALLY FOR FREE

    You just click "Play" and the money will start coming into your life. starting almost INSTANTLY.

    GO here to play the marvelous "Miracle Abundance Tone" - it's my gift to you!!!

    回覆刪除