2013-03-24 13 views
6

Son Linux çekirdeği (en azından amd64 üzerinde), syscall arabirimini çekirdeğe ayıran ve çekirdeğin en uygun çağrı kuralını seçmesini sağlayan linux-vdso.so.1 adlı bir sihirli nesne dosyası sağlar. C dilinde kod yazarsanız, glibc bu nesneyi otomatik olarak kullanır.Kendi programlama dilinizle VDSO nesnesinden nasıl yararlanılır?

Şimdi, glibc'yi kullanmadan bir program yazmak istersem, bu nesneyi nasıl kullanabilirim? Sağladığı arabirim bir yerde belgelenmiş mi? Arayan kongre ne olacak?

+0

Merak etme, syscalls için * C * arabirimini kullanmayan diliniz nedir? Bunun için ücretsiz bir yazılım uygulaması sağlıyor musunuz? –

+0

@Basile Forth'ın nasıl çalıştığını öğrenmek için bir Forth yazmaya çalışıyorum. Herhangi bir kütüphane olmaksızın, [jonesforth] (http://git.annexia.org/?p=jonesforth.git) 'e benzer bir şekilde programlamak istiyorum. VDSO nesnesi, sistem çağrılarını uygulamak için güzel ve verimli bir yoldur. – fuz

cevap

6

ya da değil.

Dil sen VDSO kullanmak gerekmez C sarmalayıcı aracılığıyla gitmeden sistem çağrıları doğrudan erişim sağlar (çünkü örneğin syscall yapmak uygun SYSENTER makine talimat yaratabilir). Bu durumda, dilinizin tüm ABI sözleşmelerini, sadece çekirdeğin kurallarını izlemesine bile gerek yoktur. (Örneğin, ABI'ye, yazmaçlar üzerinde arayan güvenli, güvenli güvenli ayırıcıya ihtiyacınız yoktur ve hatta herhangi bir yığın kullanmamanız da mümkündür).

VDSO hakkındaki bilgim, çekirdek tarafından sağlanan çeşitli küçük farklılıkları (kullanıcı-toprak -> çekirdek geçişleri ile ilgili), x86 işlemcilerinin çeşitli aileleri arasında syscall'ların uygulanmasındaki bir soyutlamadır. Belirli bir işlemci hedefini seçtiyseniz, VDSO'ya ihtiyacınız yoktur ve her zaman bundan kaçınabilirsiniz.

AFAIU, VDSO, ffffffffff600000-ffffffffff601000 numaralı segmentte (en son derlenmiş bir 3.8.3 çekirdeğiyle Debian/AMD64 üzerinde) oturan bir ELF paylaşılan nesnesidir; Tam olarak cat /proc/self/maps ile kontrol edin). Yani sadece ELF'nin paylaşılan nesnelerinin organizasyonunu anlamalı ve ondan semboller almalısınız. this & that bağlantılarına bakın. VDSO, x86-64 ABI belirtiminde belgelenen çağrı için C kurallarını kullanır. Eğer işlem alanına VDSO ayıklamak ve bir disk dosyasına üzerine yazarsam olduğu

, sonuç iyi oluşturulmuş ELF paylaşılan nesne

ELF iyi belgelenmiş biçimi olmasıdır. Ve böylece x86-64 ABI conventions (tam olarak C çağırma kurallarını ve tam olarak bir işlemin görüntüsünün nasıl başladığını tanımlar. Ayrıca bkz. execve(2)) man sayfası ve tabiki çekirdek belgeleri, bu yüzden sorunun ne olduğunu anlamıyorum. ELF'yi anlamanın zaman aldığını kabul ediyorum (bunu 10 yıl önce yaptım, ama hafızam paslı). Ayrıca makinenizdeki <elf.h> başlık dosyasını da okuyun.

Örneğin; çalışan (zsh 64 bit altında 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] 

bakınız this answer.

Muhtemelen çalışma zamanınızın içinde VDSO'yu basitçe ayrıştırabilen dinamik bir bağlayıcının en az bir sürümünü istiyorsunuz.Bir sürecin başlatıldığı kesin durumu ve özellikle de yardımcı vektörü (auxv) rolünü kesinlikle anlamak istersiniz (bu ayrıntıları gerçekten unutuyorum, fakat bunların önemli olduğunu hatırlıyorum). Bakınız örn. this article

Aslında, güvenilir bir şekilde başlama zamanınız muhtemelen VDSO sorunundan daha zordur.

Ayrıca

BTW, http://musl-libc.org/ kodu (alternatif libc olan) çok daha kolay okunur ve bir (x86-64 daha x86 ilgili değil ama daha çok) aynı zamanda bazı şeyleri açıklıyor linux assembly howto okumak isteyebilirsiniz Ben yararlı Linux çekirdeği ağacında bu dosyaları bulundu

+0

Glibc'nin herhangi bir bölümünü kullanmadan bir programlama dili için bir çalışma zamanı kitaplığı uygulamaya çalışıyorum. Çıplak talimatları sarmalayan sistem çağrıları için ilkellere ihtiyacım var. Bir sistem çağrısı yapmak için mevcut en hızlı yöntemi kullandığı için VDSO'yu hız için kullanmak isterim. – fuz

+0

Ardından, önce onu tasarlayın ve uygulayın ve daha sonra optimize edin. VDSO, özellikle yeni bir programlama dilinde (çoğu program syscall-bound değil, kullanıcı-CPU veya IO-bound) bir optimizasyon ve uygulamada gerçekten önemli değil, bu yüzden VDSO çok önemli değil. AFAIK, statik olarak bağlantılı ikili dosyalar (hatta C), adres alanlarında kalsa bile VDSO'yu kullanmaz. –

+0

Cevabınız ve yorumunuz, sorularımın hiçbirine hitap etmiyor."Howto A" diye sorduğumda ve cevap temelde "Bir sonra" deyince çok yararsızdır. – fuz

4

internet kazma günü ben bu bağlantıyı

http://www.linuxjournal.com/content/creating-vdso-colonels-other-chicken

Ben sorunuza yanıt düşünüyorum bulundu

uygulamanız Ci düşük seviyeli programlar için arabirimini kullanıyorsa Duruma göre
+0

Bu makale hiç yardımcı olmuyor. Çekirdek tarafında VDSO'ya nasıl bir syscall eklemeyi açıklar; Bu, kullanıcı tarafıyla ilgili hemen hemen hiçbir şey söylemiyor, eğer zaten bağlıysa, o nesneyi nasıl alacağımız dışında (glibc olmadan derleme yapmam durum böyle değil). – fuz

+2

VDSO, Glibc olmadan bile büyülü olarak bağlanır. Diğer Libc'lerin bunu nasıl yaptığını anlayabilirsiniz. Http://musl-libc.org/ kaynak kodunu çok okunabilir buluyorum (bir çok önişlemci hilesi kullanan Glibc'den daha fazlası). –

+0

@Basile Bir nesne dosyasını -nostdlib ile derleyin ve ardından bağlı olan lib'leri dökmek için ldd a.out'u yapın; linux-vdso.so.1 listelenmiyor. (Glibc'yi kullanırsanız). – fuz

4

(.. ve onlar vb dinamik bağlama, pthreads, nasıl kolayca öğreneceksiniz) anlama:

vDSO nesne daima Linux altında bir amd64'tür işlemin adres boşlukta haritalandınlır sanal dinamik ortak amacıdır. Hızlı sistem çağrılarını uygulamak için kullanılabilir. vDSO nesnesinin içinde işlevlere erişmek için, iki şey CC0 lisanslı referans uygulanması parse_vdso.c ile yapılabilir simge tablosuna

gelen nesneyi

  • özü bir adres bulmak

    • gerekir.

  • İlgili konular