Tergantung apakah implementasi Anda menggunakan C antarmuka untuk utilitas tingkat rendah atau tidak.
Jika implementasi bahasa Anda memberikan akses langsung ke syscalls tanpa melalui C pembungkus Anda tidak perlu menggunakan VDSO (misalnya Anda dapat membuat SYSENTER
yang sesuai instruksi mesin untuk melakukan syscall), tetapi Anda dapat memutuskan untuk menggunakan VDSO dan kemudian memanfaatkannya. Dalam hal ini, bahasa Anda bahkan tidak perlu mengikuti semua konvensi ABI, hanya konvensi kernel. (misalnya, Anda tidak memerlukan ABI yang menyediakan caller-safe calle-safe distinguo pada register, dan Anda bahkan dapat menghindari penggunaan tumpukan apa pun).
Contoh implementasi bahasa bahkan tidak menggunakan libc.so
adalah Skema Tulang. Anda dapat menemukan beberapa lainnya.
Pemahaman saya tentang VDSO adalah bahwa ini adalah abstraksi, yang disediakan oleh kernel, untuk mengabstraksi berbagai perbedaan kecil (terkait dengan user-land -> transisi kernel) dalam mengimplementasikan syscall, antara berbagai keluarga prosesor x86. Jika Anda telah memilih target prosesor tertentu, Anda tidak memerlukan VDSO, dan Anda selalu dapat menghindarinya.
AFAIU, VDSO adalah objek bersama ELF, duduk (di Debian/AMD64 saya dengan kernel 3.8.3 yang baru dikompilasi) di segmen ffffffffff600000-ffffffffff601000
; periksa persis dengan cat /proc/self/maps
dimana). Jadi, Anda hanya perlu memahami organisasi objek bersama ELF dan mengambil simbol darinya. Lihat tautan ini &itu. VDSO menggunakan konvensi C untuk pemanggilan yang didokumentasikan dalam spesifikasi ABI x86-64.
ELF adalah format yang terdokumentasi dengan baik. Begitu juga dengan konvensi ABI x86-64 (yang mendefinisikan dengan tepat konvensi pemanggilan C, dan bagaimana sebenarnya gambar proses dimulai. Lihat juga halaman manual execve(2)), dan tentu saja dokumentasi kernel, jadi saya tidak mengerti apa masalahmu. Saya setuju bahwa memahami ELF membutuhkan waktu (saya melakukannya 10 tahun yang lalu, tetapi ingatan saya berkarat). Baca juga <elf.h>
file header di komputer Anda.
Contohnya; berjalan (di bawah zsh
pada 64 bit 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]
Lihat juga jawaban ini.
Anda mungkin ingin di dalam runtime Anda versi minimal linker dinamis yang dapat dengan mudah mengurai VDSO. Anda tentu ingin memahami keadaan sebenarnya saat proses dimulai, dan khususnya peran auxv
, vektor bantu (saya benar-benar lupa detail ini, tapi saya ingat itu penting). Lihat mis. artikel ini
Sebenarnya, memulai runtime Anda dengan andal mungkin lebih sulit daripada masalah VDSO.
Anda mungkin juga ingin membaca cara rakitan linux yang juga menjelaskan beberapa hal (tetapi lebih banyak tentang x86 daripada x86-64)
BTW, kode http://musl-libc.org/ (yang merupakan libc alternatif) jauh lebih mudah dibaca dan dipahami (dan Anda akan belajar dengan mudah bagaimana mereka melakukan penautan dinamis, pthreads, dll..)
Saya menemukan file-file ini di pohon kernel Linux sangat membantu:
Documentation/ABI/stable/vdso
(apa objek vDSO?)Documentation/vDSO/parse_vdso.c
(Pengurai referensi untuk objek vDSO)
Objek vDSO adalah objek bersama dinamis virtual yang selalu dipetakan ke ruang alamat proses amd64 di linux. Ini dapat digunakan untuk mengimplementasikan panggilan sistem cepat. Untuk mengakses fungsi di dalam objek vDSO, Anda perlu
- cari objeknya
- ekstrak alamat dari tabel simbol
Kedua hal tersebut dapat dilakukan dengan penerapan referensi berlisensi CC0 parse_vdso.c.