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
Merak etme, syscalls için * C * arabirimini kullanmayan diliniz nedir? Bunun için ücretsiz bir yazılım uygulaması sağlıyor musunuz? –
@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